题目:需要巩固

· · 个人记录

平衡树

P2584 [ZJOI2006]GameZ游戏排名系统-Treap版

P4291 [HAOI2008]排名系统-Splay版

(以上两题为重题,但数据不同)

P1110 ZJOI2007报表统计

P1486 NOI2004郁闷的出纳员

P2596 ZJOI2006书架

P2042 NOI2005维护数列

扫描线

P1856 [USACO5.5]矩形周长Picture

差分约束

#10088. 「一本通 3.4 例 2」出纳员问题

剩余系

P2662 牛场围栏

网络流

P4174 NOI2006最大获利

P1486 NOI2004郁闷的出纳员

P2857 USACO06FEB稳定奶牛分配Steady Cow Assignment

P2754 CTSC1999家园

线段树

P2572 [SCOI2010]序列操作 注意操作优先级, [code]

#include <bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define ls (nod<<1)
#define rs (nod<<1|1)
#define lson ls,l,mid
#define rson rs,mid+1,r

int read(){
    int x=0; char c; int flag=1;
    for(c=getchar();!isdigit(c);c=getchar()) if(c=='-') flag=-1;
    for(;isdigit(c);c=getchar()) x=((x+(x<<2))<<1)+(c^48);
    return x*flag;
}

const int N=1e5+50;
int n,m;
struct node{
    int l,r;
    int len;

    int tag;
    int rev;

    int l0,r0,s0,x0;
    int l1,r1,s1,x1;

}t[N<<2];

void pushup(int nod){
    if(t[nod].l==t[nod].r) return ;

    if(t[ls].l0==t[ls].len) t[nod].l0=t[ls].l0+t[rs].l0; else t[nod].l0=t[ls].l0;
    if(t[ls].l1==t[ls].len) t[nod].l1=t[ls].l1+t[rs].l1; else t[nod].l1=t[ls].l1;

    if(t[rs].r0==t[rs].len) t[nod].r0=t[rs].r0+t[ls].r0; else t[nod].r0=t[rs].r0;
    if(t[rs].r1==t[rs].len) t[nod].r1=t[rs].r1+t[ls].r1; else t[nod].r1=t[rs].r1;

    t[nod].s0=t[ls].s0+t[rs].s0;
    t[nod].s1=t[ls].s1+t[rs].s1;

    t[nod].x0=max(max(t[ls].x0,t[rs].x0),t[ls].r0+t[rs].l0);
    t[nod].x1=max(max(t[ls].x1,t[rs].x1),t[ls].r1+t[rs].l1);
}

void pushdown(int nod){
    if(t[nod].l==t[nod].r) return ;
    if(t[nod].tag!=-1){
        int x=t[nod].tag; t[nod].tag=-1;
        if(x==0){
            t[ls].l0=t[ls].r0=t[ls].s0=t[ls].x0=t[ls].len;
            t[ls].l1=t[ls].r1=t[ls].s1=t[ls].x1=0;

            t[rs].l0=t[rs].r0=t[rs].s0=t[rs].x0=t[rs].len;
            t[rs].l1=t[rs].r1=t[rs].s1=t[rs].x1=0;
        }
        else{
            t[ls].l0=t[ls].r0=t[ls].s0=t[ls].x0=0;
            t[ls].l1=t[ls].r1=t[ls].s1=t[ls].x1=t[ls].len;

            t[rs].l0=t[rs].r0=t[rs].s0=t[rs].x0=0;
            t[rs].l1=t[rs].r1=t[rs].s1=t[rs].x1=t[rs].len;
        }
        t[ls].tag=t[rs].tag=x;
        t[ls].rev=t[rs].rev=0;
    }

    if(t[nod].rev!=0){
        t[nod].rev=0;
        t[ls].rev^=1; t[rs].rev^=1;
        swap(t[ls].l0,t[ls].l1); swap(t[ls].r0,t[ls].r1);
        swap(t[ls].s0,t[ls].s1); swap(t[ls].x0,t[ls].x1);

        swap(t[rs].l0,t[rs].l1); swap(t[rs].r0,t[rs].r1);
        swap(t[rs].s0,t[rs].s1); swap(t[rs].x0,t[rs].x1);
    }
}

void build(int nod,int l,int r){
    t[nod].l=l; t[nod].r=r; t[nod].len=r-l+1;
    t[nod].tag=-1; t[nod].rev=0;

    if(l==r){
        int x=read();
        if(x==1) t[nod].l1=t[nod].r1=t[nod].s1=t[nod].x1=1;
        else t[nod].l0=t[nod].r0=t[nod].s0=t[nod].x0=1;
        return ; 
    }

    build(lson); build(rson);
    pushup(nod);
}

void update(int nod,int l,int r,int ll,int rr,int v){
    if(l==ll&&r==rr){
        if(v==0){
            t[nod].tag=0; t[nod].rev=0;
            t[nod].l1=t[nod].r1=t[nod].s1=t[nod].x1=0;
            t[nod].l0=t[nod].r0=t[nod].s0=t[nod].x0=t[nod].len;
        }else if(v==1){
            t[nod].tag=1; t[nod].rev=0;
            t[nod].l1=t[nod].r1=t[nod].s1=t[nod].x1=t[nod].len;
            t[nod].l0=t[nod].r0=t[nod].s0=t[nod].x0=0;
        }else if(v==2){
            t[nod].rev^=1;
            swap(t[nod].l1,t[nod].l0);swap(t[nod].r1,t[nod].r0);
            swap(t[nod].s1,t[nod].s0);swap(t[nod].x1,t[nod].x0);
        }
        return ;
    }
    pushdown(nod);
    if(rr<=mid) update(lson,ll,rr,v);
    else if(ll>mid) update(rson,ll,rr,v);
    else update(lson,ll,mid,v),update(rson,mid+1,rr,v);
    pushup(nod);
}

node query(int nod,int l,int r,int ll,int rr){
    if(l==ll&&r==rr) return t[nod];
    pushdown(nod);
    if(rr<=mid) return query(lson,ll,rr);
    else if(ll>mid) return query(rson,ll,rr);
    else{
        node tmp1=query(lson,ll,mid);
        node tmp2=query(rson,mid+1,rr);
        node tmp;
        tmp.l=l; tmp.r=r; tmp.len=r-l+1;
        if(tmp1.l0==tmp1.len) tmp.l0=tmp1.l0+tmp2.l0; else tmp.l0=tmp1.l0;
        if(tmp1.l1==tmp1.len) tmp.l1=tmp1.l1+tmp2.l1; else tmp.l1=tmp1.l1;

        if(tmp2.r0==tmp2.len) tmp.r0=tmp2.r0+tmp1.r0; else tmp.r0=tmp2.r0;
        if(tmp2.r1==tmp2.len) tmp.r1=tmp2.r1+tmp1.r1; else tmp.r1=tmp2.r1;

        tmp.s0=tmp1.s0+tmp2.s0;
        tmp.s1=tmp1.s1+tmp2.s1;

        tmp.x0=max(max(tmp1.x0,tmp2.x0),tmp1.r0+tmp2.l0);
        tmp.x1=max(max(tmp1.x1,tmp2.x1),tmp1.r1+tmp2.l1);
        return tmp;
    }
}

signed main() {
    n=read(),m=read();
    build(1,1,n);
    while(m--){
        int opt=read(),l=read()+1,r=read()+1;
        if(opt<=2) update(1,1,n,l,r,opt);
        else{
            node tmp=query(1,1,n,l,r);
            if(opt==3) printf("%d\n",tmp.s1);
            else printf("%d\n",tmp.x1);
        }
    }
    return 0;
}

P1438 无聊的数列 树状数组的区间修改,区间查询

[code]

#include <bits/stdc++.h>
using namespace std;

int read(){
    int x=0; char c; int flag=1;
    for(c=getchar();!isdigit(c);c=getchar()) if(c=='-') flag=-1;
    for(;isdigit(c);c=getchar()) x=((x+(x<<2))<<1)+(c^48);
    return x*flag;
}

const int N=1e5+50;
int n,m;
int a[N];

int c[N],d[N];

int lowbit(int x){
    return x&(-x);
}
int query(int x){
    int ret=0;
    for(int i=x;i>0;i-=lowbit(i)) ret+=(x+1)*c[i]-d[i];
    return ret;
}
void update(int x,int y){
    for(int i=x;i<=n;i+=lowbit(i)) c[i]+=y,d[i]+=x*y;
}
void qj(int l,int r,int v){
    update(l,v);
    update(r+1,-v);
}
signed main() {
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    while(m--){
        int opt=read();
        if(opt==1){
            int l=read(),r=read(),k=read(),D=read();
            qj(l,l,k);
            qj(l+1,r,D);
            qj(r+1,r+1,-k-D*(r-l));
        }
        else{
            int p=read();
            printf("%d\n",query(p)+a[p]);
        }    
    }

    return 0;
}

杂题

[ZJOI2003] 密码机

树状数组维护异或和

#include <bits/stdc++.h>
using namespace std;

int read(){
    int x=0; char c; int flag=1;
    for(c=getchar();!isdigit(c);c=getchar()) if(c=='-') flag=-1;
    for(;isdigit(c);c=getchar()) x=((x+(x<<2))<<1)+(c^48);
    return x*flag;
}

const int N=2e5;
int c[N+10];

int lowbit(int x) { return x&(-x); }
void update(int x){
    for(int i=x;i<=N;i+=lowbit(i)) 
    c[i]^=x;
}
int query(int x){
    int ret=0;
    for(int i=x;i>0;i-=lowbit(i)) ret^=c[i];
    return ret;
}

int main() {
    char opt;
    while(scanf(" %c",&opt)!=EOF){
        if(opt=='A'){
            int x;
            scanf("DD %d",&x);
            update(x);
        }else if(opt=='R'){
            int x;
            scanf("EMOVE %d",&x);
            update(x);
        }else{
            int x,y;
            scanf("OR BETWEEN %d AND %d",&x,&y);
            if(x>y) printf("0\n");
            else
            printf("%d\n",query(y)^query(x-1));
        }
    }
    return 0;
}