一些数据结构题目的代码片段

  自从暑假洗心革面怒艹数据结构以来,从我手中通过的题,其代码量就基本没低于100行……到现在虽然还有很多题不会搞,却也可以简单地写一些东西,并整理出个可堪一用的板子了。接下来提到的基本是各种树形数据结构的入门级题目和提高级题目,绝大多数来自Damocles数据结构专题训练,主要给队友参考吧。

  HDU1754

  难度一颗星;单点替换,区间最值。树状数组、线段树、Splay各一发。

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=200005;
int bit[MAXN],num[MAXN],n;
inline int lowbit(int x) {
    return x&-x;
}
void modify(int x,int val) {
    num[x]=val;
    for(int i=x; i<=n; i+=lowbit(i)) {
        bit[i]=max(bit[i],val);
        for(int j=1; j<lowbit(i); j<<=1)
            bit[i]=max(bit[i],bit[i-j]);
    }
}
int query(int L,int R) {
    int ret=num[R];
    while(true) {
        ret=max(ret,num[R]);
        if(L==R)
            break;
        for(R-=1; R-L>=lowbit(R); R-=lowbit(R))
            ret=max(ret,bit[R]);
    }
    return ret;
}
int main() {
    int q,a,b;
    char op;
    while(~scanf("%d%d",&n,&q)) {
        memset(bit,0,sizeof(bit));
        for(int i=1; i<=n; ++i) {
            scanf("%d",&b);
            modify(i,b);
        }
        while(q--) {
            scanf(" %c%d%d",&op,&a,&b);
            switch(op) {
            case 'Q':
                printf("%d\n",query(a,b));
                break;
            case 'U':
                modify(a,b);
                break;
            }
        }
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=200005;
int maxv[MAXN<<2];
void PushUp(int rt) {
    maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);
}
void build(int l,int r,int rt) {
    if(l==r) {
        scanf("%d",&maxv[rt]);
        return;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int p,int val,int l,int r,int rt) {
    if(l==r) {
        maxv[rt]=val;
        return;
    }
    int m=l+r>>1;
    if(p<=m)
        update(p,val,lson);
    else
        update(p,val,rson);
    PushUp(rt);
}
int query(int L,int R,int l,int r,int rt) {
    if(L<=l&&r<=R)
        return maxv[rt];
    int m=l+r>>1,ret=0;
    if(L<=m)
        ret=max(ret,query(L,R,lson));
    if(m<R)
        ret=max(ret,query(L,R,rson));
    return ret;
}
int main() {
    int n,q,a,b;
    char op;
    while(~scanf("%d%d",&n,&q)) {
        build(1,n,1);
        while(q--) {
            scanf(" %c%d%d",&op,&a,&b);
            switch(op) {
            case 'Q':
                printf("%d\n",query(a,b,1,n,1));
                break;
            case 'U':
                update(a,b,1,n,1);
                break;
            }
        }
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
#define keyTree ch[ch[root][1]][0]
const int MAXN=200005;
struct Splay {
    int tot,root;
    int ch[MAXN][2],pre[MAXN],size[MAXN];
    void rotate(int x,int f) {
        int y=pre[x];
        ch[y][f^1]=ch[x][f];
        pre[ch[x][f]]=y;
        pre[x]=pre[y];
        if(pre[x])
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        ch[x][f]=y;
        pre[y]=x;
        push_up(y);
    }
    void splay(int x,int goal) {
        while(pre[x]!=goal)
            if(pre[pre[x]]==goal)
                rotate(x,ch[pre[x]][0]==x);
            else {
                int y=pre[x],z=pre[y],f=ch[z][0]==y;
                if(ch[y][f]==x)
                    rotate(x,f^1);
                else
                    rotate(y,f);
                rotate(x,f);
            }
        push_up(x);
        if(goal==0)
            root=x;
    }
    void rotate_to(int k,int goal) {
        int x=root;
        while(size[ch[x][0]]!=k)
            if(k<size[ch[x][0]])
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        splay(x,goal);
    }
    void NewNode(int &x,int c,int fa) {
        x=++tot;
        ch[x][0]=ch[x][1]=0;
        size[x]=1;
        pre[x]=fa;
        val[x]=vmax[x]=c;
    }
    void push_up(int x) {
        size[x]=size[ch[x][0]]+1+size[ch[x][1]];
        vmax[x]=max(val[x],max(vmax[ch[x][0]],vmax[ch[x][1]]));
    }
    void build(int &x,int l,int r,int f) {
        if(l>r)
            return;
        int m=l+r>>1;
        NewNode(x,num[m],f);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        push_up(x);
    }
    void init(int n) {
        root=tot=0;
        ch[0][0]=ch[0][1]=size[0]=0;
        vmax[0]=0;
        NewNode(root,-1,0);
        NewNode(ch[root][1],-1,root);
        size[root]=2;
        for(int i=1; i<=n; ++i)
            scanf("%d",&num[i]);
        build(keyTree,1,n,ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
    }
    void update(int p,int v) {
        rotate_to(p-1,0);
        rotate_to(p+1,root);
        val[keyTree]=v;
        vmax[keyTree]=max(vmax[keyTree],v);
    }
    long long query(int l,int r) {
        rotate_to(l-1,0);
        rotate_to(r+1,root);
        return vmax[keyTree];
    }
    int num[MAXN],val[MAXN],vmax[MAXN];
} splay;
int main() {
    int n,q,a,b;
    char op;
    while(~scanf("%d%d",&n,&q)) {
        splay.init(n);
        while(q--) {
            scanf(" %c%d%d",&op,&a,&b);
            switch(op) {
            case 'Q':
                printf("%d\n",splay.query(a,b));
                break;
            case 'U':
                splay.update(a,b);
                break;
            }
        }
    }
}

  POJ3468

  难度一星半;区间增减,区间求和,树状数组、线段树、Splay各一发。

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=100005;
long long bit1[MAXN],bit2[MAXN];
int n;
inline int lowbit(int x) {
    return x&-x;
}
void add(int x,int val) {
    for(int i=x; i>0; i-=lowbit(i))
        bit1[i]+=val;
    for(int i=x; i<=n; i+=lowbit(i))
        bit2[i]+=x*(long long)val;
}
long long sum(int x) {
    if(!x)
        return 0;
    long long sum1=0,sum2=0;
    for(int i=x; i<=n; i+=lowbit(i))
        sum1+=bit1[i];
    for(int i=x-1; i>0; i-=lowbit(i))
        sum2+=bit2[i];
    return sum1*x+sum2;
}
int main() {
    int q,a,b,c;
    char op;
    while(~scanf("%d%d",&n,&q)) {
        memset(bit1,0,sizeof(bit1));
        memset(bit2,0,sizeof(bit2));
        for(int i=1; i<=n; ++i) {
            scanf("%d",&c);
            add(i,c);
            if(i>1)
                add(i-1,-c);
        }
        while(q--) {
            scanf(" %c%d%d",&op,&a,&b);
            switch(op) {
            case 'Q':
                printf("%I64d\n",sum(b)-sum(a-1));
                break;
            case 'C':
                scanf("%d",&c);
                add(b,c);
                if(a>1)
                    add(a-1,-c);
                break;
            }
        }
    }
}
#include<cstdio>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=100005;
long long sum[MAXN<<2],col[MAXN<<2];
void PushUp(int rt) {
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt,int m) {
    if(col[rt]) {
        col[rt<<1]+=col[rt];
        col[rt<<1|1]+=col[rt];
        sum[rt<<1]+=col[rt]*(m-(m>>1));
        sum[rt<<1|1]+=col[rt]*(m>>1);
        col[rt]=0;
    }
}
void build(int l,int r,int rt) {
    col[rt]=0;
    if(l==r) {
        scanf("%I64d",&sum[rt]);
        return;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int L,int R,int val,int l,int r,int rt) {
    if(L<=l&&r<=R) {
        col[rt]+=val;
        sum[rt]+=val*(r-l+1);
        return;
    }
    PushDown(rt,r-l+1);
    int m=l+r>>1;
    if(L<=m)
        update(L,R,val,lson);
    if(m<R)
        update(L,R,val,rson);
    PushUp(rt);
}
long long query(int L,int R,int l,int r,int rt) {
    if(L<=l&&r<=R)
        return sum[rt];
    PushDown(rt,r-l+1);
    int m=l+r>>1;
    long long ret=0;
    if(L<=m)
        ret+=query(L,R,lson);
    if(m<R)
        ret+=query(L,R,rson);
    return ret;
}
int main() {
    int n,q,a,b,c;
    char op;
    while(~scanf("%d%d",&n,&q)) {
        build(1,n,1);
        while(q--) {
            scanf(" %c%d%d",&op,&a,&b);
            switch(op) {
            case 'Q':
                printf("%I64d\n",query(a,b,1,n,1));
                break;
            case 'C':
                scanf("%d",&c);
                update(a,b,c,1,n,1);
                break;
            }
        }
    }
}
#include<cstdio>
using namespace std;
#define keyTree ch[ch[root][1]][0]
const int MAXN=100005;
struct Splay {
    int root,tot;
    int ch[MAXN][2],pre[MAXN],size[MAXN];
    void rotate(int x,int f) {
        int y=pre[x];
        ch[y][f^1]=ch[x][f];
        pre[ch[x][f]]=y;
        pre[x]=pre[y];
        if(pre[x])
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        ch[x][f]=y;
        pre[y]=x;
        push_up(y);
    }
    void splay(int x,int goal) {
        push_down(x);
        while(pre[x]!=goal) {
            int y=pre[x],z=pre[y];
            if(z==goal) {
                push_down(y);
                push_down(x);
                rotate(x,ch[y][0]==x);
            } else {
                push_down(z);
                push_down(y);
                push_down(x);
                int f=ch[z][0]==y;
                if(ch[y][f]==x)
                    rotate(x,f^1);
                else
                    rotate(y,f);
                rotate(x,f);
            }
        }
        push_up(x);
        if(goal==0)
            root=x;
    }
    void rotate_to(int k,int goal) {
        int x=root;
        push_down(x);
        while(size[ch[x][0]]!=k) {
            if(k<size[ch[x][0]])
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
            push_down(x);
        }
        splay(x,goal);
    }
    void NewNode(int &x,int c,int fa) {
        x=++tot;
        ch[x][0]=ch[x][1]=0;
        pre[x]=fa;
        size[x]=1;
        val[x]=sum[x]=c;
        add[x]=0;
    }
    void push_up(int x) {
        size[x]=size[ch[x][0]]+1+size[ch[x][1]];
        sum[x]=val[x]+sum[ch[x][0]]+sum[ch[x][1]];
    }
    void push_down(int x) {
        if(add[x]) {
            val[x]+=add[x];
            add[ch[x][0]]+=add[x];
            add[ch[x][1]]+=add[x];
            sum[ch[x][0]]+=(long long)size[ch[x][0]]*add[x];
            sum[ch[x][1]]+=(long long)size[ch[x][1]]*add[x];
            add[x]=0;
        }
    }
    void build(int &x,int l,int r,int f) {
        if(l>r)
            return;
        int m=l+r>>1;
        NewNode(x,num[m],f);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        push_up(x);
    }
    void init(int n) {
        root=tot=0;
        ch[0][0]=ch[0][1]=size[0]=0;
        add[0]=sum[0]=0;
        NewNode(root,-1,0);
        NewNode(ch[root][1],-1,root);
        size[root]=2;
        for(int i=1; i<=n; ++i)
            scanf("%d",&num[i]);
        build(keyTree,1,n,ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
    }
    void update(int l,int r,int v) {
        rotate_to(l-1,0);
        rotate_to(r+1,root);
        add[keyTree]+=v;
        sum[keyTree]+=(long long)v*size[keyTree];
    }
    long long query(int l,int r) {
        rotate_to(l-1,0);
        rotate_to(r+1,root);
        return sum[keyTree];
    }
    int num[MAXN],val[MAXN],add[MAXN];
    long long sum[MAXN];
} splay;
int main() {
    int n,q,a,b,c;
    char op;
    while(~scanf("%d%d",&n,&q)) {
        splay.init(n);
        while(q--) {
            scanf(" %c%d%d",&op,&a,&b);
            switch(op) {
            case 'Q':
                printf("%I64d\n",splay.query(a,b));
                break;
            case 'C':
                scanf("%d",&c);
                splay.update(a,b,c);
                break;
            }
        }
    }
}

  POJ3667

  难度两颗星;区间合并。线段树一发。

#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=50005;
int cnt[MAXN<<2],lcnt[MAXN<<2],rcnt[MAXN<<2],mark[MAXN<<2];
void push_up(int rt,int len) {
    cnt[rt]=max(rcnt[rt<<1]+lcnt[rt<<1|1],max(cnt[rt<<1],cnt[rt<<1|1]));
    lcnt[rt]=lcnt[rt<<1];
    if(lcnt[rt]==len-(len>>1))
        lcnt[rt]+=lcnt[rt<<1|1];
    rcnt[rt]=rcnt[rt<<1|1];
    if(rcnt[rt]==(len>>1))
        rcnt[rt]+=rcnt[rt<<1];
}
void push_down(int rt,int len) {
    if(~mark[rt]) {
        cnt[rt<<1]=lcnt[rt<<1]=rcnt[rt<<1]=mark[rt]?0:len-(len>>1);
        cnt[rt<<1|1]=lcnt[rt<<1|1]=rcnt[rt<<1|1]=mark[rt]?0:(len>>1);
        mark[rt<<1]=mark[rt<<1|1]=mark[rt];
        mark[rt]=-1;
    }
}
void build(int l,int r,int rt) {
    mark[rt]=-1;
    cnt[rt]=lcnt[rt]=rcnt[rt]=r-l+1;
    if(l==r)
        return;
    int m=l+r>>1;
    build(lson);
    build(rson);
}
void update(int L,int R,int col,int l,int r,int rt) {
    if(L<=l&&r<=R) {
        cnt[rt]=lcnt[rt]=rcnt[rt]=col?0:r-l+1;
        mark[rt]=col;
        return;
    }
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(L<=m)
        update(L,R,col,lson);
    if(m<R)
        update(L,R,col,rson);
    push_up(rt,r-l+1);
}
int query(int len,int l,int r,int rt) {
    if(cnt[rt]<len)
        return 0;
    if(l==r)
        return l;
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(cnt[rt<<1]>=len)
        return query(len,lson);
    else if(rcnt[rt<<1]+lcnt[rt<<1|1]>=len)
        return m+1-rcnt[rt<<1];
    else if(cnt[rt<<1|1]>=len)
        return query(len,rson);
}
int main() {
    int n,m,op,x,d,ans;
    while(~scanf("%d%d",&n,&m)) {
        build(1,n,1);
        while(m--) {
            scanf("%d",&op);
            switch(op) {
            case 1:
                scanf("%d",&d);
                ans=query(d,1,n,1);
                printf("%d\n",ans);
                if(ans)
                    update(ans,ans+d-1,1,1,n,1);
                break;
            case 2:
                scanf("%d%d",&x,&d);
                update(x,x+d-1,0,1,n,1);
                break;
            }
        }
    }
}

  HDU2871

  难度两星半;区间合并。两种姿势线段树各一发。

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=50005;
int cnt[MAXN<<2],lcnt[MAXN<<2],rcnt[MAXN<<2],mark[MAXN<<2];
void push_up(int rt,int len) {
    cnt[rt]=max(rcnt[rt<<1]+lcnt[rt<<1|1],max(cnt[rt<<1],cnt[rt<<1|1]));
    lcnt[rt]=lcnt[rt<<1];
    if(lcnt[rt]==len-(len>>1))
        lcnt[rt]+=lcnt[rt<<1|1];
    rcnt[rt]=rcnt[rt<<1|1];
    if(rcnt[rt]==(len>>1))
        rcnt[rt]+=rcnt[rt<<1];
}
void push_down(int rt,int len) {
    if(~mark[rt]) {
        cnt[rt<<1]=lcnt[rt<<1]=rcnt[rt<<1]=mark[rt]?0:len-(len>>1);
        cnt[rt<<1|1]=lcnt[rt<<1|1]=rcnt[rt<<1|1]=mark[rt]?0:(len>>1);
        mark[rt<<1]=mark[rt<<1|1]=mark[rt];
        mark[rt]=-1;
    }
}
void build(int l,int r,int rt) {
    mark[rt]=-1;
    cnt[rt]=lcnt[rt]=rcnt[rt]=r-l+1;
    if(l==r)
        return;
    int m=l+r>>1;
    build(lson);
    build(rson);
}
void update(int L,int R,int col,int l,int r,int rt) {
    if(L<=l&&r<=R) {
        cnt[rt]=lcnt[rt]=rcnt[rt]=col?0:r-l+1;
        mark[rt]=col;
        return;
    }
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(L<=m)
        update(L,R,col,lson);
    if(m<R)
        update(L,R,col,rson);
    push_up(rt,r-l+1);
}
int query(int len,int l,int r,int rt) {
    if(l==r)
        return l;
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(cnt[rt<<1]>=len)
        return query(len,lson);
    else if(rcnt[rt<<1]+lcnt[rt<<1|1]>=len)
        return m+1-rcnt[rt<<1];
    else if(cnt[rt<<1|1]>=len)
        return query(len,rson);
}
vector<pair<int,int> > block;
vector<pair<int,int> >::iterator it;
int main() {
    int n,m,x,a;
    char op[8];
    pair<int,int> tmp;
    while(~scanf("%d%d",&n,&m)) {
        build(1,n,1);
        block.clear();
        while(m--) {
            scanf("%s",op);
            switch(op[0]) {
            case 'R':
                update(1,n,0,1,n,1);
                block.clear();
                puts("Reset Now");
                break;
            case 'N':
                scanf("%d",&x);
                if(cnt[1]>=x) {
                    a=query(x,1,n,1);
                    update(a,a+x-1,1,1,n,1);
                    tmp=make_pair(a,a+x-1);
                    it=upper_bound(block.begin(),block.end(),tmp);
                    block.insert(it,tmp);
                    printf("New at %d\n",a);
                } else
                    puts("Reject New");
                break;
            case 'F':
                scanf("%d",&x);
                it=upper_bound(block.begin(),block.end(),make_pair(x,n+1));
                if(it==block.begin())
                    puts("Reject Free");
                else {
                    --it;
                    if(it->second<x)
                        puts("Reject Free");
                    else {
                        update(it->first,it->second,0,1,n,1);
                        printf("Free from %d to %d\n",it->first,it->second);
                        block.erase(it);
                    }
                }
                break;
            case 'G':
                scanf("%d",&x);
                if(x<=block.size())
                    printf("Get at %d\n",block[x-1].first);
                else
                    puts("Reject Get");
                break;
            }
        }
        putchar('\n');
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=50005;
int cnt[MAXN<<2],lcnt[MAXN<<2],rcnt[MAXN<<2],mark[MAXN<<2],start[MAXN<<2],end[MAXN<<2],num[MAXN<<2];
bool cover[MAXN<<2];
void push_up(int rt,int len) {
    cnt[rt]=max(rcnt[rt<<1]+lcnt[rt<<1|1],max(cnt[rt<<1],cnt[rt<<1|1]));
    lcnt[rt]=lcnt[rt<<1];
    if(lcnt[rt]==len-(len>>1))
        lcnt[rt]+=lcnt[rt<<1|1];
    rcnt[rt]=rcnt[rt<<1|1];
    if(rcnt[rt]==(len>>1))
        rcnt[rt]+=rcnt[rt<<1];
}
void push_down(int rt,int len) {
    if(~mark[rt]) {
        cnt[rt<<1]=lcnt[rt<<1]=rcnt[rt<<1]=mark[rt]?0:len-(len>>1);
        cnt[rt<<1|1]=lcnt[rt<<1|1]=rcnt[rt<<1|1]=mark[rt]?0:(len>>1);
        start[rt<<1]=start[rt<<1|1]=start[rt];
        end[rt<<1]=end[rt<<1|1]=end[rt];
        mark[rt<<1]=mark[rt<<1|1]=mark[rt];
        mark[rt]=-1;
    }
}
void update(int L,int R,int col,int l,int r,int rt) {
    if(L<=l&&r<=R) {
        cnt[rt]=lcnt[rt]=rcnt[rt]=col?0:r-l+1;
        mark[rt]=col;
        if(col) {
            start[rt]=L;
            end[rt]=R;
        } else
            start[rt]=end[rt]=-1;
        return;
    }
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(L<=m)
        update(L,R,col,lson);
    if(m<R)
        update(L,R,col,rson);
    push_up(rt,r-l+1);
}
int New(int len,int l,int r,int rt) {
    if(l==r)
        return l;
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(cnt[rt<<1]>=len)
        return New(len,lson);
    else if(rcnt[rt<<1]+lcnt[rt<<1|1]>=len)
        return m+1-rcnt[rt<<1];
    else if(cnt[rt<<1|1]>=len)
        return New(len,rson);
}
int Free(int p,int l,int r,int rt) {
    if(l==r)
        return rt;
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(p<=m)
        return Free(p,lson);
    else
        return Free(p,rson);
}
void count_up(int rt) {
    num[rt]=num[rt<<1]+num[rt<<1|1];
}
void count_down(int rt) {
    if(cover[rt]) {
        num[rt<<1]=num[rt<<1|1]=0;
        cover[rt<<1]=cover[rt<<1|1]=cover[rt];
        cover[rt]=false;
    }
}
void count(int p,int val,int l,int r,int rt) {
    if(l==r) {
        num[rt]=val;
        return;
    }
    count_down(rt);
    int m=l+r>>1;
    if(p<=m)
        count(p,val,lson);
    else
        count(p,val,rson);
    count_up(rt);
}
int Get(int k,int l,int r,int rt) {
    if(l==r)
        return l;
    int m=l+r>>1;
    count_down(rt);
    if(num[rt<<1]>=k)
        return Get(k,lson);
    else
        return Get(k-num[rt<<1],rson);
}
int main() {
    int n,m,x,a;
    char op[8];
    while(~scanf("%d%d",&n,&m)) {
        update(1,n,0,1,n,1);
        cover[1]=true;
        num[1]=0;
        while(m--) {
            scanf("%s",op);
            switch(op[0]) {
            case 'R':
                puts("Reset Now");
                update(1,n,0,1,n,1);
                cover[1]=true;
                num[1]=0;
                break;
            case 'N':
                scanf("%d",&x);
                if(cnt[1]>=x) {
                    a=New(x,1,n,1);
                    printf("New at %d\n",a);
                    count(a,1,1,n,1);
                    update(a,a+x-1,1,1,n,1);
                } else
                    puts("Reject New");
                break;
            case 'F':
                scanf("%d",&x);
                a=Free(x,1,n,1);
                if(~start[a]) {
                    printf("Free from %d to %d\n",start[a],end[a]);
                    count(start[a],0,1,n,1);
                    update(start[a],end[a],0,1,n,1);
                } else
                    puts("Reject Free");
                break;
            case 'G':
                scanf("%d",&x);
                if(num[1]>=x)
                    printf("Get at %d\n",Get(x,1,n,1));
                else
                    puts("Reject Get");
                break;
            }
        }
        putchar('\n');
    }
}

  HDU4902

  难度两星半;区间带限制覆盖,区间最值,多重lazy标记。线段树一发。

#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N=100005;
int cover[N<<2],vmax[N<<2];
bool same[N<<2];
void push_up(int rt) {
    vmax[rt]=max(vmax[rt<<1],vmax[rt<<1|1]);
    same[rt]=same[rt<<1]&&same[rt<<1|1]&&vmax[rt<<1]==vmax[rt<<1|1];
}
void push_down(int rt) {
    if(cover[rt]) {
        vmax[rt<<1]=vmax[rt<<1|1]=cover[rt<<1]=cover[rt<<1|1]=cover[rt];
        cover[rt]=0;
    }
    if(same[rt])
        same[rt<<1]=same[rt<<1|1]=true;
}
void build(int l,int r,int rt) {
    cover[rt]=0;
    same[rt]=false;
    if(l==r) {
        scanf("%d",&vmax[rt]);
        return;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    push_up(rt);
}
void upcover(int L,int R,int v,int l,int r,int rt) {
    if(L<=l&&r<=R) {
        vmax[rt]=cover[rt]=v;
        same[rt]=true;
        return;
    }
    push_down(rt);
    int m=l+r>>1;
    if(L<=m)
        upcover(L,R,v,lson);
    if(m<R)
        upcover(L,R,v,rson);
    push_up(rt);
}
void upgcd(int L,int R,int v,int l,int r,int rt) {
    if(vmax[rt]<=v)
        return;
    if(l==r||(L<=l&&r<=R&&same[rt])) {
        cover[rt]=vmax[rt]=__gcd(vmax[rt],v);
        same[rt]=true;
        return;
    }
    push_down(rt);
    int m=l+r>>1;
    if(L<=m)
        upgcd(L,R,v,lson);
    if(m<R)
        upgcd(L,R,v,rson);
    push_up(rt);
}
int query(int p,int l,int r,int rt) {
    if(l==r)
        return vmax[rt];
    push_down(rt);
    int m=l+r>>1;
    if(p<=m)
        return query(p,lson);
    else
        return query(p,rson);
}
int main() {
    int T,n,q,a,t,l,r,x;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        build(1,n,1);
        scanf("%d",&q);
        while(q--) {
            scanf("%d%d%d%d",&t,&l,&r,&x);
            switch(t) {
            case 1:
                upcover(l,r,x,1,n,1);
                break;
            case 2:
                upgcd(l,r,x,1,n,1);
                break;
            }
        }
        for(int i=1; i<=n; ++i)
            printf("%d ",query(i,1,n,1));
        putchar('\n');
    }
}

  HDU4819

  难度三颗星;二维平面单点修改,区间最值。四分树、二维线段树各一发。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define tl xl,xm,yl,ym,rt<<2
#define tr xl,xm,ym+1,yr,(rt<<2)+1
#define dl xm+1,xr,yl,ym,(rt<<2)+2
#define dr xm+1,xr,ym+1,yr,(rt<<2)+3
const int MAXN=805;
const int INF=0x3f3f3f3f;
int vmax[MAXN<<12],vmin[MAXN<<12];
void push_up(int rt) {
    vmax[rt]=max(max(vmax[rt<<2],vmax[(rt<<2)+1]),max(vmax[(rt<<2)+2],vmax[(rt<<2)+3]));
    vmin[rt]=min(min(vmin[rt<<2],vmin[(rt<<2)+1]),min(vmin[(rt<<2)+2],vmin[(rt<<2)+3]));
}
void update(int x,int y,int v,int xl,int xr,int yl,int yr,int rt) {
    if(xl==xr&&yl==yr) {
        vmax[rt]=vmin[rt]=v;
        return;
    }
    int xm=xl+xr>>1,ym=yl+yr>>1;
    if(x<=xm) {
        if(y<=ym)
            update(x,y,v,tl);
        else
            update(x,y,v,tr);
    } else {
        if(y<=ym)
            update(x,y,v,dl);
        else
            update(x,y,v,dr);
    }
    push_up(rt);
}
pair<int,int> query(int xL,int xR,int yL,int yR,int xl,int xr,int yl,int yr,int rt) {
    if(xL<=xl&&xr<=xR&&yL<=yl&&yr<=yR)
        return make_pair(vmax[rt],vmin[rt]);
    int xm=xl+xr>>1,ym=yl+yr>>1,retmax=0,retmin=INF;
    pair<int,int> tmp;
    if(xL<=xm&&yL<=ym) {
        tmp=query(xL,xR,yL,yR,tl);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    if(xL<=xm&&yR>ym) {
        tmp=query(xL,xR,yL,yR,tr);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    if(xR>xm&&yL<=ym) {
        tmp=query(xL,xR,yL,yR,dl);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    if(xR>xm&&yR>ym) {
        tmp=query(xL,xR,yL,yR,dr);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    return make_pair(retmax,retmin);
}
int main() {
    int t,n,v,q,x,y,l;
    scanf("%d",&t);
    for(int cas=1; cas<=t; ++cas) {
        scanf("%d",&n);
        memset(vmax,0,sizeof(vmax));
        memset(vmin,0x3f,sizeof(vmin));
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j) {
                scanf("%d",&v);
                update(i,j,v,1,n,1,n,1);
            }
        scanf("%d",&q);
        printf("Case #%d:\n",cas);
        while(q--) {
            scanf("%d%d%d",&x,&y,&l);
            pair<int,int> ans=query(max(x-l/2,1),min(x+l/2,n),max(y-l/2,1),min(y+l/2,n),1,n,1,n,1);
            printf("%d\n",(ans.first+ans.second)/2);
            update(x,y,(ans.first+ans.second)/2,1,n,1,n,1);
        }
    }
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=805;
const int INF=0x3f3f3f3f;
int vmax[MAXN<<2][MAXN<<2],vmin[MAXN<<2][MAXN<<2],n;
void push_up(int x,int rt) {
    vmax[x][rt]=max(vmax[x][rt<<1],vmax[x][rt<<1|1]);
    vmin[x][rt]=min(vmin[x][rt<<1],vmin[x][rt<<1|1]);
}
void push_up1(int x,int rt) {
    vmax[x][rt]=max(vmax[x<<1][rt],vmax[x<<1|1][rt]);
    vmin[x][rt]=min(vmin[x<<1][rt],vmin[x<<1|1][rt]);
}
void build(int x,int l,int r,int rt) {
    vmax[x][rt]=0;
    vmin[x][rt]=INF;
    if(l==r)
        return;
    int m=l+r>>1;
    build(x,lson);
    build(x,rson);
}
void build(int l,int r,int rt) {
    if(l==r) {
        build(rt,1,n,1);
        return;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
}
void update2(int x,int p,int v,int l,int r,int rt) {
    if(l==r) {
        vmax[x][rt]=vmin[x][rt]=v;
        return;
    }
    int m=l+r>>1;
    if(p<=m)
        update2(x,p,v,lson);
    else
        update2(x,p,v,rson);
    push_up(x,rt);
}
void update1(int x,int p,int v,int l,int r,int rt) {
    if(l==r) {
        push_up1(x,rt);
        return;
    }
    int m=l+r>>1;
    if(p<=m)
        update1(x,p,v,lson);
    else
        update1(x,p,v,rson);
    push_up(x,rt);
}
void update(int p,int q,int v,int l,int r,int rt) {
    if(l==r) {
        update2(rt,q,v,1,n,1);
        return;
    }
    int m=l+r>>1;
    if(p<=m)
        update(p,q,v,lson);
    else
        update(p,q,v,rson);
    update1(rt,q,v,1,n,1);
}
pair<int,int> query(int x,int L,int R,int l,int r,int rt) {
    if(L<=l&&r<=R)
        return make_pair(vmax[x][rt],vmin[x][rt]);
    int m=l+r>>1,retmax=0,retmin=INF;
    pair<int,int> tmp;
    if(L<=m) {
        tmp=query(x,L,R,lson);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    if(m<R) {
        tmp=query(x,L,R,rson);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    return make_pair(retmax,retmin);
}
pair<int,int> query(int xL,int xR,int yL,int yR,int l,int r,int rt) {
    if(xL<=l&&r<=xR)
        return query(rt,yL,yR,1,n,1);
    int m=l+r>>1,retmax=0,retmin=INF;
    pair<int,int> tmp;
    if(xL<=m) {
        tmp=query(xL,xR,yL,yR,lson);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    if(m<xR) {
        tmp=query(xL,xR,yL,yR,rson);
        retmax=max(retmax,tmp.first);
        retmin=min(retmin,tmp.second);
    }
    return make_pair(retmax,retmin);
}
int main() {
    int t,v,q,x,y,l;
    scanf("%d",&t);
    for(int cas=1; cas<=t; ++cas) {
        scanf("%d",&n);
        build(1,n,1);
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j) {
                scanf("%d",&v);
                update(i,j,v,1,n,1);
            }
        scanf("%d",&q);
        printf("Case #%d:\n",cas);
        while(q--) {
            scanf("%d%d%d",&x,&y,&l);
            pair<int,int> ans=query(max(x-l/2,1),min(x+l/2,n),max(y-l/2,1),min(y+l/2,n),1,n,1);
            printf("%d\n",(ans.first+ans.second)/2);
            update(x,y,(ans.first+ans.second)/2,1,n,1);
        }
    }
}

  POJ3321

  难度两颗星;树上单点修改,子树求和。树上dfs序+树状数组、树上dfs序+线段树各一发。

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1000005;
const int MAXM=MAXN;
struct graph {
    int head[MAXN];
    int to[MAXM],next[MAXM];
    int tot;
    void init() {
        tot=0;
        memset(head,0xff,sizeof(head));
    }
    void add(int u,int v) {
        to[tot]=v;
        next[tot]=head[u];
        head[u]=tot++;
    }
} g;
int bit[MAXN],n;
inline int lowbit(int x) {
    return x&-x;
}
void add(int x,int val) {
    for(int i=x; i<=n; i+=lowbit(i))
        bit[i]+=val;
}
int sum(int x) {
    int ret=0;
    for(int i=x; i>0; i-=lowbit(i))
        ret+=bit[i];
    return ret;
}
int low[MAXN],high[MAXN],cnt;
void dfs(int u) {
    low[u]=++cnt;
    for(int i=g.head[u]; ~i; i=g.next[i])
        dfs(g.to[i]);
    high[u]=cnt;
}
int main() {
    int u,v,m,x;
    char op;
    while(~scanf("%d",&n)) {
        g.init();
        for(int i=1; i<n; ++i) {
            scanf("%d%d",&u,&v);
            g.add(u,v);
        }
        cnt=0;
        dfs(1);
        memset(bit,0,sizeof(bit));
        for(int i=1; i<=n; ++i)
            add(i,1);
        scanf("%d",&m);
        while(m--) {
            scanf(" %c%d",&op,&x);
            switch(op) {
            case 'C':
                add(low[x],!(sum(low[x])-sum(low[x]-1))?1:-1);
                break;
            case 'Q':
                printf("%d\n",sum(high[x])-sum(low[x]-1));
                break;
            }
        }
    }
}
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1000005;
const int MAXM=MAXN;
struct graph {
    int head[MAXN];
    int to[MAXM],next[MAXM];
    int tot;
    void init() {
        tot=0;
        memset(head,0xff,sizeof(head));
    }
    void add(int u,int v) {
        to[tot]=v;
        next[tot]=head[u];
        head[u]=tot++;
    }
} g;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[MAXN<<2];
void push_up(int rt) {
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt) {
    if(l==r) {
        sum[rt]=1;
        return;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    push_up(rt);
}
void update(int p,int val,int l,int r,int rt) {
    if(l==r) {
        sum[rt]+=val;
        return;
    }
    int m=l+r>>1;
    if(p<=m)
        update(p,val,lson);
    else
        update(p,val,rson);
    push_up(rt);
}
int query(int L,int R,int l,int r,int rt) {
    if(L<=l&&r<=R)
        return sum[rt];
    int m=l+r>>1,ret=0;
    if(L<=m)
        ret+=query(L,R,lson);
    if(m<R)
        ret+=query(L,R,rson);
    return ret;
}
int low[MAXN],high[MAXN],cnt;
void dfs(int u) {
    low[u]=++cnt;
    for(int i=g.head[u]; ~i; i=g.next[i])
        dfs(g.to[i]);
    high[u]=cnt;
}
int main() {
    int n,u,v,m,x;
    char op;
    while(~scanf("%d",&n)) {
        g.init();
        for(int i=1; i<n; ++i) {
            scanf("%d%d",&u,&v);
            g.add(u,v);
        }
        cnt=0;
        dfs(1);
        build(1,n,1);
        scanf("%d",&m);
        while(m--) {
            scanf(" %c%d",&op,&x);
            switch(op) {
            case 'C':
                update(low[x],!query(low[x],low[x],1,n,1)?1:-1,1,n,1);
                break;
            case 'Q':
                printf("%d\n",query(low[x],high[x],1,n,1));
                break;
            }
        }
    }
}

  HDU3887

  难度两星半;树上单点修改,子树带限制求和。树上dfs序+树状数组、树上dfs序+线段树各一发。

#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int MAXN=100005;
const int MAXM=MAXN<<1;
struct graph {
    int head[MAXN];
    int to[MAXM],next[MAXM];
    int tot;
    void init() {
        tot=0;
        memset(head,0xff,sizeof(head));
    }
    void add(int u,int v) {
        to[tot]=v;
        next[tot]=head[u];
        head[u]=tot++;
    }
} g;
int bit[MAXN],n;
inline int lowbit(int x) {
    return x&-x;
}
void add(int x,int val) {
    for(int i=x; i<=n; i+=lowbit(i))
        bit[i]+=val;
}
int sum(int x) {
    int ret=0;
    for(int i=x; i>0; i-=lowbit(i))
        ret+=bit[i];
    return ret;
}
int ans[MAXN];
void dfs(int u,int pre) {
    add(u,1);
    ans[u]=sum(u);
    for(int i=g.head[u]; ~i; i=g.next[i]) {
        int v=g.to[i];
        if(v!=pre)
            dfs(v,u);
    }
    ans[u]=sum(u)-ans[u];
}
int main() {
    int __size__=16<<20;
    char *__p__=(char*)malloc(__size__)+__size__;
    __asm__("movl %0, %%esp\n"::"r"(__p__));
    int p,u,v;
    while(~scanf("%d%d",&n,&p)&&(n||p)) {
        g.init();
        for(int i=1; i<n; ++i) {
            scanf("%d%d",&u,&v);
            g.add(u,v);
            g.add(v,u);
        }
        memset(bit,0,sizeof(bit));
        dfs(p,-1);
        for(int i=1; i<=n; ++i) {
            printf("%d",ans[i]);
            putchar(i<n?' ':'\n');
        }
    }
}
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int MAXN=100005;
const int MAXM=MAXN<<1;
struct graph {
    int head[MAXN];
    int to[MAXM],next[MAXM];
    int tot;
    void init() {
        tot=0;
        memset(head,0xff,sizeof(head));
    }
    void add(int u,int v) {
        to[tot]=v;
        next[tot]=head[u];
        head[u]=tot++;
    }
} g;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[MAXN<<2];
void build(int l,int r,int rt) {
    sum[rt]=0;
    if(l==r)
        return;
    int m=l+r>>1;
    build(lson);
    build(rson);
}
void update(int p,int val,int l,int r,int rt) {
    if(l==r) {
        sum[rt]+=val;
        return;
    }
    int m=l+r>>1;
    if(p<=m)
        update(p,val,lson);
    else
        update(p,val,rson);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int query(int L,int R,int l,int r,int rt) {
    if(L<=l&&r<=R)
        return sum[rt];
    int m=l+r>>1,ret=0;
    if(L<=m)
        ret+=query(L,R,lson);
    if(m<R)
        ret+=query(L,R,rson);
    return ret;
}
int ans[MAXN],n;
void dfs(int u,int pre) {
    update(u,1,1,n,1);
    ans[u]=query(1,u,1,n,1);
    for(int i=g.head[u]; ~i; i=g.next[i]) {
        int v=g.to[i];
        if(v!=pre)
            dfs(v,u);
    }
    ans[u]=query(1,u,1,n,1)-ans[u];
}
int main() {
    int __size__=16<<20;
    char *__p__=(char*)malloc(__size__)+__size__;
    __asm__("movl %0, %%esp\n"::"r"(__p__));
    int p,u,v;
    while(~scanf("%d%d",&n,&p)&&(n||p)) {
        g.init();
        for(int i=1; i<n; ++i) {
            scanf("%d%d",&u,&v);
            g.add(u,v);
            g.add(v,u);
        }
        build(1,n,1);
        dfs(p,-1);
        for(int i=1; i<=n; ++i) {
            printf("%d",ans[i]);
            putchar(i<n?' ':'\n');
        }
    }
}

  HDU3966

  难度三颗星;树上路径修改,单点查询。树上dfs序+LCA+树状数组、树链剖分+树状数组、树链剖分+线段树各一发。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=50005;
const int MAXM=MAXN<<1;
struct graph {
    int head[MAXN];
    int to[MAXM],next[MAXM];
    int tot;
    void init() {
        tot=0;
        memset(head,0xff,sizeof(head));
    }
    void add(int u,int v) {
        to[tot]=v;
        next[tot]=head[u];
        head[u]=tot++;
    }
} g;
const int maxd=18;
int low[MAXN],high[MAXN],cnt;
int d[MAXN],f[MAXN][maxd];
void dfs(int u,int fa) {
    low[u]=++cnt;
    f[u][0]=fa;
    d[u]=d[fa]+1;
    for(int i=1; i<maxd; ++i)
        f[u][i]=f[f[u][i-1]][i-1];
    for(int i=g.head[u]; ~i; i=g.next[i]) {
        int v=g.to[i];
        if(v!=fa)
            dfs(v,u);
    }
    high[u]=++cnt;
}
int lca(int u,int v) {
    if(d[u]<d[v])
        swap(u,v);
    int k=d[u]-d[v];
    for(int i=0; i<maxd; ++i)
        if((1<<i)&k)
            u=f[u][i];
    if(u==v)
        return u;
    for(int i=maxd-1; i>=0; --i)
        if(f[u][i]!=f[v][i]) {
            u=f[u][i];
            v=f[v][i];
        }
    return f[u][0];
}
int bit[MAXN<<1];
inline int lowbit(int x) {
    return x&-x;
}
void add(int x,int val) {
    for(int i=x; i>0; i-=lowbit(i))
        bit[i]+=val;
}
int get(int x) {
    int ret=0;
    for(int i=x; i<=cnt; i+=lowbit(i))
        ret+=bit[i];
    return ret;
}
void modify(int x,int y,int d) {
    add(low[x],d);
    add(low[y],d);
    int fa=lca(x,y);
    add(low[fa]-1,-d);
    add(low[fa],-d);
}
int a[MAXN];
int main() {
    int n,m,p,u,v,c,k;
    char op;
    while(~scanf("%d%d%d",&n,&m,&p)) {
        for(int i=1; i<=n; ++i)
            scanf("%d",&a[i]);
        g.init();
        while(m--) {
            scanf("%d%d",&u,&v);
            g.add(u,v);
            g.add(v,u);
        }
        cnt=0;
        dfs(1,-1);
        memset(bit,0,sizeof(bit));
        while(p--) {
            scanf(" %c",&op);
            switch(op) {
            case 'I':
                scanf("%d%d%d",&u,&v,&k);
                modify(u,v,k);
                break;
            case 'D':
                scanf("%d%d%d",&u,&v,&k);
                modify(u,v,-k);
                break;
            case 'Q':
                scanf("%d",&c);
                printf("%d\n",a[c]+get(low[c])-get(high[c]));
                break;
            }
        }
    }
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=50005;
const int MAXM=MAXN<<1;
struct graph {
    int head[MAXN];
    int to[MAXM],next[MAXM];
    int tot;
    void init() {
        tot=0;
        memset(head,0xff,sizeof(head));
    }
    void add(int u,int v) {
        to[tot]=v;
        next[tot]=head[u];
        head[u]=tot++;
    }
} g;
int top[MAXN],len[MAXN];
int belong[MAXN],idx[MAXN];
int dep[MAXN],fa[MAXN],size[MAXN];
int que[MAXN];
bool vis[MAXN];
int n,cnt;
void split() {
    memset(dep,0xff,sizeof(dep));
    int l=0,r=0;
    que[++r]=1;
    dep[1]=0;
    fa[1]=-1;
    while(l<r) {
        int u=que[++l];
        vis[u]=false;
        for(int i=g.head[u]; ~i; i=g.next[i]) {
            int v=g.to[i];
            if(!~dep[v]) {
                que[++r]=v;
                dep[v]=dep[u]+1;
                fa[v]=u;
            }
        }
    }
    cnt=0;
    for(int i=n; i>0; --i) {
        int u=que[i],p=-1;
        size[u]=1;
        for(int j=g.head[u]; ~j; j=g.next[j]) {
            int v=g.to[j];
            if(vis[v]) {
                size[u]+=size[v];
                if(!~p||size[v]>size[p])
                    p=v;
            }
        }
        if(!~p) {
            idx[u]=len[++cnt]=1;
            belong[u]=cnt;
            top[cnt]=u;
        } else {
            belong[u]=belong[p];
            idx[u]=++len[belong[u]];
            top[belong[u]]=u;
        }
        vis[u]=true;
    }
}
int fi[MAXN],cid[MAXN],rank[MAXN];
void getcid() {
    fi[1]=1;
    for(int i=2; i<=cnt; ++i)
        fi[i]=fi[i-1]+len[i-1];
    for(int i=1; i<=n; ++i) {
        cid[i]=fi[belong[i]]+len[belong[i]]-idx[i];
        rank[cid[i]]=i;
    }
}
int bit[MAXN];
inline int lowbit(int x) {
    return x&-x;
}
void add(int x,int val) {
    for(int i=x; i>0; i-=lowbit(i))
        bit[i]+=val;
}
int sum(int x) {
    int ret=0;
    for(int i=x; i<=n; i+=lowbit(i))
        ret+=bit[i];
    return ret;
}
void modify(int x,int y,int d) {
    while(belong[x]!=belong[y]) {
        if(dep[top[belong[x]]]<dep[top[belong[y]]])
            swap(x,y);
        add(cid[top[belong[x]]]-1,-d);
        add(cid[x],d);
        x=fa[top[belong[x]]];
    }
    if(dep[x]>dep[y])
        swap(x,y);
    add(cid[x]-1,-d);
    add(cid[y],d);
}
int a[MAXN];
int main() {
    int m,p,u,v,c,k;
    char op;
    while(~scanf("%d%d%d",&n,&m,&p)) {
        for(int i=1; i<=n; ++i)
            scanf("%d",&a[i]);
        g.init();
        while(m--) {
            scanf("%d%d",&u,&v);
            g.add(u,v);
            g.add(v,u);
        }
        split();
        getcid();
        memset(bit,0,sizeof(bit));
        while(p--) {
            scanf(" %c",&op);
            switch(op) {
            case 'I':
                scanf("%d%d%d",&u,&v,&k);
                modify(u,v,k);
                break;
            case 'D':
                scanf("%d%d%d",&u,&v,&k);
                modify(u,v,-k);
                break;
            case 'Q':
                scanf("%d",&c);
                printf("%d\n",a[c]+sum(cid[c]));
                break;
            }
        }
    }
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=50005;
const int MAXM=MAXN<<1;
struct graph {
    int head[MAXN];
    int to[MAXM],next[MAXM];
    int tot;
    void init() {
        tot=0;
        memset(head,0xff,sizeof(head));
    }
    void add(int u,int v) {
        to[tot]=v;
        next[tot]=head[u];
        head[u]=tot++;
    }
} g;
int top[MAXN],len[MAXN];
int belong[MAXN],idx[MAXN];
int dep[MAXN],fa[MAXN],size[MAXN];
int que[MAXN];
bool vis[MAXN];
int n,cnt;
void split() {
    memset(dep,0xff,sizeof(dep));
    int l=0,r=0;
    que[++r]=1;
    dep[1]=0;
    fa[1]=-1;
    while(l<r) {
        int u=que[++l];
        vis[u]=false;
        for(int i=g.head[u]; ~i; i=g.next[i]) {
            int v=g.to[i];
            if(!~dep[v]) {
                que[++r]=v;
                dep[v]=dep[u]+1;
                fa[v]=u;
            }
        }
    }
    cnt=0;
    for(int i=n; i>0; --i) {
        int u=que[i],p=-1;
        size[u]=1;
        for(int j=g.head[u]; ~j; j=g.next[j]) {
            int v=g.to[j];
            if(vis[v]) {
                size[u]+=size[v];
                if(!~p||size[v]>size[p])
                    p=v;
            }
        }
        if(!~p) {
            idx[u]=len[++cnt]=1;
            belong[u]=cnt;
            top[cnt]=u;
        } else {
            belong[u]=belong[p];
            idx[u]=++len[belong[u]];
            top[belong[u]]=u;
        }
        vis[u]=true;
    }
}
int a[MAXN],fi[MAXN],cid[MAXN],rank[MAXN];
void getcid() {
    fi[1]=1;
    for(int i=2; i<=cnt; ++i)
        fi[i]=fi[i-1]+len[i-1];
    for(int i=1; i<=n; ++i) {
        cid[i]=fi[belong[i]]+len[belong[i]]-idx[i];
        rank[cid[i]]=i;
    }
}
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[MAXN<<2],col[MAXN<<2];
void push_up(int rt) {
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(int rt,int len) {
    if(col[rt]) {
        col[rt<<1]+=col[rt];
        col[rt<<1|1]+=col[rt];
        sum[rt<<1]+=col[rt]*(len-(len>>1));
        sum[rt<<1|1]+=col[rt]*(len>>1);
        col[rt]=0;
    }
}
void build(int l,int r,int rt) {
    col[rt]=0;
    if(l==r) {
        sum[rt]=a[rank[l]];
        return;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    push_up(rt);
}
void update(int L,int R,int val,int l,int r,int rt) {
    if(L<=l&&r<=R) {
        col[rt]+=val;
        sum[rt]+=val*(r-l+1);
        return;
    }
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(L<=m)
        update(L,R,val,lson);
    if(m<R)
        update(L,R,val,rson);
    push_up(rt);
}
int query(int p,int l,int r,int rt) {
    if(l==r)
        return sum[rt];
    push_down(rt,r-l+1);
    int m=l+r>>1;
    if(p<=m)
        return query(p,lson);
    else
        return query(p,rson);
}
void modify(int x,int y,int d) {
    while(belong[x]!=belong[y]) {
        if(dep[top[belong[x]]]<dep[top[belong[y]]])
            swap(x,y);
        update(cid[top[belong[x]]],cid[x],d,1,n,1);
        x=fa[top[belong[x]]];
    }
    if(dep[x]>dep[y])
        swap(x,y);
    update(cid[x],cid[y],d,1,n,1);
}
int main() {
    int m,p,u,v,c,k;
    char op;
    while(~scanf("%d%d%d",&n,&m,&p)) {
        for(int i=1; i<=n; ++i)
            scanf("%d",&a[i]);
        g.init();
        while(m--) {
            scanf("%d%d",&u,&v);
            g.add(u,v);
            g.add(v,u);
        }
        split();
        getcid();
        build(1,n,1);
        while(p--) {
            scanf(" %c",&op);
            switch(op) {
            case 'I':
                scanf("%d%d%d",&u,&v,&k);
                modify(u,v,k);
                break;
            case 'D':
                scanf("%d%d%d",&u,&v,&k);
                modify(u,v,-k);
                break;
            case 'Q':
                scanf("%d",&c);
                printf("%d\n",query(cid[c],1,n,1));
                break;
            }
        }
    }
}

  POJ3481

  难度一颗星;平衡树插入、删除。Treap、Size Balanced Tree、Skip List各一发。

#include<cstdio>
#include<cstdlib>
using namespace std;
const int MAXN=1000005;
const int INF=0x3f3f3f3f;
struct Treap {
    int tot,root;
    int ch[MAXN][2],key[MAXN],pt[MAXN],size[MAXN],val[MAXN];
    Treap() {
        tot=1;
        root=0;
        pt[0]=INF;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    bool insert(int &x,int k,int v) {
        if(!x) {
            x=tot++;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            val[x]=v;
            pt[x]=rand();
            size[x]=1;
            return true;
        }
        if(key[x]==k)
            return false;
        int t=key[x]<k;
        if(!insert(ch[x][t],k,v))
            return false;
        ++size[x];
        if(pt[ch[x][t]]<pt[x])
            rotate(x,t);
        return true;
    }
    bool erase(int &x,int k) {
        if(!x)
            return false;
        if(key[x]!=k) {
            if(!erase(ch[x][key[x]<k],k))
                return false;
            --size[x];
        } else if(!ch[x][0]&&!ch[x][1])
            x=0;
        else if(!ch[x][0])
            x=ch[x][1];
        else if(!ch[x][1])
            x=ch[x][0];
        else {
            rotate(x,pt[ch[x][0]]>pt[ch[x][1]]);
            if(!erase(ch[x][key[x]<k],k))
                return false;
            --size[x];
        }
        return true;
    }
    void insert(int k,int v) {
        insert(root,k,v);
    }
    void erase(int k) {
        erase(root,k);
    }
    int getMin(int x) {
        while(ch[x][0])
            x=ch[x][0];
        return x;
    }
    int getMax(int x) {
        while(ch[x][1])
            x=ch[x][1];
        return x;
    }
    int getLow() {
        if(size[root]==0)
            return 0;
        int x=getMin(root),ret=val[x];
        erase(key[x]);
        return ret;
    }
    int getHigh() {
        if(size[root]==0)
            return 0;
        int x=getMax(root),ret=val[x];
        erase(key[x]);
        return ret;
    }
} treap;
int main() {
    int op,k,p;
    while(~scanf("%d",&op)&&op)
        switch(op) {
        case 1:
            scanf("%d%d",&k,&p);
            treap.insert(p,k);
            break;
        case 2:
            printf("%d\n",treap.getHigh());
            break;
        case 3:
            printf("%d\n",treap.getLow());
            break;
        }
}
#include<cstdio>
using namespace std;
const int MAXN=1000005;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN],val[MAXN];
    SBT() {
        tot=1;
        root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        } else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    void insert(int &x,int k,int v) {
        if(x==0) {
            x=tot++;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            val[x]=v;
            size[x]=1;
        } else {
            ++size[x];
            insert(ch[x][k>=key[x]],k,v);
            Maintain(x,k>=key[x]);
        }
    }
    int erase(int &x,int k) {
        --size[x];
        if(key[x]==k||(k<key[x]&&ch[x][0]==0)||(k>key[x]&&ch[x][1]==0)) {
            int ret=key[x];
            if(ch[x][0]&&ch[x][1])
                key[x]=erase(ch[x][0],key[x]+1);
            else
                x=ch[x][0]+ch[x][1];
        } else
            return erase(ch[x][k>=key[x]],k);
    }
    void insert(int k,int v) {
        insert(root,k,v);
    }
    void erase(int k) {
        erase(root,k);
    }
    int getMin(int x) {
        while(ch[x][0])
            x=ch[x][0];
        return x;
    }
    int getMax(int x) {
        while(ch[x][1])
            x=ch[x][1];
        return x;
    }
    int getLow() {
        if(size[root]==0)
            return 0;
        int x=getMin(root),ret=val[x];
        erase(key[x]);
        return ret;
    }
    int getHigh() {
        if(size[root]==0)
            return 0;
        int x=getMax(root),ret=val[x];
        erase(key[x]);
        return ret;
    }
} sbt;
int main() {
    int op,k,p;
    while(~scanf("%d",&op)&&op)
        switch(op) {
        case 1:
            scanf("%d%d",&k,&p);
            sbt.insert(p,k);
            break;
        case 2:
            printf("%d\n",sbt.getHigh());
            break;
        case 3:
            printf("%d\n",sbt.getLow());
            break;
        }
}
#include<cstdio>
#include<cstdlib>
using namespace std;
const int MAX_LEVEL=18;
struct SkipList {
    struct node {
        int key,val;
        node *next[1];
    };
    int level;
    node *head;
    SkipList() {
        level=0;
        head=newNode(MAX_LEVEL-1,0,0);
        for(int i=0; i<MAX_LEVEL; ++i)
            head->next[i]=NULL;
    }
    node* newNode(int level,int key,int val) {
        node *ns=(node *)malloc(sizeof(node)+level*sizeof(node*));
        ns->key=key;
        ns->val=val;
        return ns;
    }
    int randomLevel() {
        int k=1;
        while(rand()&1)
            ++k;
        return k<MAX_LEVEL?k:MAX_LEVEL;
    }
    bool insert(int key,int val) {
        node *update[MAX_LEVEL],*p=head,*q=NULL;
        for(int i=level-1; i>=0; --i) {
            while((q=p->next[i])&&q->key<key)
                p=q;
            update[i]=p;
        }
        if(q&&q->key==key)
            return false;
        int k=randomLevel();
        if(k>level) {
            for(int i=level; i<k; ++i)
                update[i]=head;
            level=k;
        }
        q=newNode(k,key,val);
        for(int i=0; i<k; ++i) {
            q->next[i]=update[i]->next[i];
            update[i]->next[i]=q;
        }
        return true;
    }
    bool erase(int key) {
        node *update[MAX_LEVEL],*p=head,*q=NULL;
        for(int i=level-1; i>=0; --i) {
            while((q=p->next[i])&&q->key<key)
                p=q;
            update[i]=p;
        }
        if(q&&q->key==key) {
            for(int i=0; i<level; ++i)
                if(update[i]->next[i]==q)
                    update[i]->next[i]=q->next[i];
            free(q);
            for(int i=level-1; i>=0; --i)
                if(!head->next[i])
                    --level;
            return true;
        }
        return false;
    }
    int getLow() {
        node *p=head->next[0];
        if(!p)
            return 0;
        int ret=p->val;
        erase(p->key);
        return ret;
    }
    int getHigh() {
        node *p=head,*q=NULL;
        for(int i=level-1; i>=0; --i)
            while((q=p->next[i])&&q)
                p=q;
        if(p==head)
            return 0;
        int ret=p->val;
        erase(p->key);
        return ret;
    }
} sl;
int main() {
    int op,k,p;
    while(~scanf("%d",&op)&&op)
        switch(op) {
        case 1:
            scanf("%d%d",&k,&p);
            sl.insert(p,k);
            break;
        case 2:
            printf("%d\n",sl.getHigh());
            break;
        case 3:
            printf("%d\n",sl.getLow());
            break;
        }
}

  POJ1442

  难度一颗星;平衡树插入、求第k小。Treap、Size Balanced Tree各一发。

#include<cstdio>
#include<cstdlib>
using namespace std;
const int MAXN=30005;
const int INF=0x3f3f3f3f;
struct Treap {
    int tot,root;
    int ch[MAXN][2],key[MAXN],pt[MAXN],size[MAXN];
    Treap() {
        tot=1;
        root=0;
        pt[0]=INF;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    bool insert(int &x,int k) {
        if(!x) {
            x=tot++;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            pt[x]=rand();
            size[x]=1;
        } else {
            int t=key[x]<k;
            ++size[x];
            insert(ch[x][t],k);
            if(pt[ch[x][t]]<pt[x])
                rotate(x,t);
        }
    }
    void insert(int k) {
        insert(root,k);
    }
    int getKth(int k) {
        int x=root;
        while(size[ch[x][0]]+1!=k)
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return key[x];
    }
};
int a[MAXN],u[MAXN];
int main() {
    int m,n;
    while(~scanf("%d%d",&m,&n)) {
        Treap treap;
        for(int i=1; i<=m; ++i)
            scanf("%d",&a[i]);
        for(int i=0; i<n; ++i)
            scanf("%d",&u[i]);
        int pos=0;
        for(int i=1; i<=m; ++i) {
            treap.insert(a[i]);
            while(i==u[pos])
                printf("%d\n",treap.getKth(++pos));
        }
    }
}
#include<cstdio>
using namespace std;
const int MAXN=30005;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN];
    SBT() {
        tot=1;
        root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        }
        else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    void insert(int &x,int k) {
        if(!x) {
            x=tot++;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            size[x]=1;
        } else {
            ++size[x];
            insert(ch[x][key[x]<k],k);
            Maintain(x,key[x]<k);
        }
    }
    void insert(int k) {
        insert(root,k);
    }
    int getKth(int k) {
        int x=root;
        while(size[ch[x][0]]+1!=k)
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return key[x];
    }
};
int a[MAXN],u[MAXN];
int main() {
    int m,n;
    while(~scanf("%d%d",&m,&n)) {
        SBT sbt;
        for(int i=1; i<=m; ++i)
            scanf("%d",&a[i]);
        for(int i=0; i<n; ++i)
            scanf("%d",&u[i]);
        int pos=0;
        for(int i=1; i<=m; ++i) {
            sbt.insert(a[i]);
            while(i==u[pos])
                printf("%d\n",sbt.getKth(++pos));
        }
    }
}

  SPOJ3273

  难度一星半;平衡树插入、删除、求第k小,求排名。Treap、两种姿势Size Balanced Tree各一发。

#include<cstdio>
#include<cstdlib>
using namespace std;
const int MAXN=200005;
const int INF=0x3f3f3f3f;
struct Treap {
    int tot,root;
    int ch[MAXN][2],key[MAXN],pt[MAXN],size[MAXN];
    Treap() {
        tot=1;
        root=0;
        pt[0]=INF;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    bool insert(int &x,int k) {
        if(!x) {
            x=tot++;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            pt[x]=rand();
            size[x]=1;
            return true;
        }
        if(key[x]==k)
            return false;
        int t=key[x]<k;
        if(!insert(ch[x][t],k))
            return false;
        ++size[x];
        if(pt[ch[x][t]]<pt[x])
            rotate(x,t);
        return true;
    }
    bool remove(int &x,int k) {
        if(!x)
            return false;
        if(key[x]!=k) {
            if(!remove(ch[x][key[x]<k],k))
                return false;
            --size[x];
        } else if(!ch[x][0]&&!ch[x][1])
            x=0;
        else if(!ch[x][0])
            x=ch[x][1];
        else if(!ch[x][1])
            x=ch[x][0];
        else {
            rotate(x,pt[ch[x][0]]>pt[ch[x][1]]);
            if(!remove(ch[x][key[x]<k],k))
                return false;
            --size[x];
        }
        return true;
    }
    void insert(int k) {
        insert(root,k);
    }
    void remove(int k) {
        remove(root,k);
    }
    int getKth(int k) {
        int x=root;
        while(size[ch[x][0]]+1!=k)
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return key[x];
    }
    int getRank(int k) {
        int ret=0,x=root;
        while(x)
            if(k<key[x])
                x=ch[x][0];
            else {
                ret+=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return ret;
    }
} treap;
int main() {
    int n,num;
    char c;
    scanf("%d",&n);
    while(n--) {
        scanf(" %c%d",&c,&num);
        switch(c) {
        case 'I':
            treap.insert(num);
            break;
        case 'D':
            treap.remove(num);
            break;
        case 'K':
            num<=treap.size[treap.root]?printf("%d\n",treap.getKth(num)):puts("invalid");
            break;
        case 'C':
            printf("%d\n",treap.getRank(num-1));
            break;
        }
    }
}
#include<cstdio>
using namespace std;
const int MAXN=200005;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN];
    SBT() {
        tot=1;
        root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        } else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    bool insert(int &x,int k) {
        if(!x) {
            x=tot++;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            size[x]=1;
            return true;
        }
        if(key[x]==k)
            return false;
        int t=k>=key[x];
        if(!insert(ch[x][t],k))
            return false;
        ++size[x];
        Maintain(x,t);
        return true;
    }
    bool remove(int &x,int k) {
        if(!x)
            return false;
        int t;
        if(key[x]==k) {
            if(!ch[x][1]) {
                x=ch[x][0];
                return true;
            }
            if(!ch[x][0]) {
                x=ch[x][1];
                return true;
            }
            int r=ch[x][1];
            while(ch[r][0])
                r=ch[r][0];
            key[x]=key[r];
            remove(ch[x][1],key[r]);
            t=0;
        } else {
            t=k<key[x];
            remove(ch[x][t^1],k);
        }
        Maintain(x,t);
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        return true;
    }
    void insert(int k) {
        insert(root,k);
    }
    void remove(int k) {
        remove(root,k);
    }
    int getKth(int k) {
        int x=root;
        while(size[ch[x][0]]+1!=k)
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return key[x];
    }
    int getRank(int k) {
        int ret=0,x=root;
        while(x)
            if(k<key[x])
                x=ch[x][0];
            else {
                ret+=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return ret;
    }
} sbt;
int main() {
    int n,num;
    char c;
    scanf("%d",&n);
    while(n--) {
        scanf(" %c%d",&c,&num);
        switch(c) {
        case 'I':
            sbt.insert(num);
            break;
        case 'D':
            sbt.remove(num);
            break;
        case 'K':
            num<=sbt.size[sbt.root]?printf("%d\n",sbt.getKth(num)):puts("invalid");
            break;
        case 'C':
            printf("%d\n",sbt.getRank(num-1));
            break;
        }
    }
}
#include<cstdio>
using namespace std;
const int MAXN=200005;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN];
    SBT() {
        tot=1;
        root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        } else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    void insert(int &x,int k) {
        if(!x) {
            x=tot++;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            size[x]=1;
        } else {
            ++size[x];
            insert(ch[x][key[x]<k],k);
            Maintain(x,key[x]<k);
        }
    }
    int remove(int &x,int k) {
        --size[x];
        if(key[x]==k||(key[x]>k&&ch[x][0]==0)||(key[x]<k&&ch[x][1]==0)) {
            int ret=key[x];
            if(ch[x][0]&&ch[x][1])
                key[x]=remove(ch[x][0],key[x]+1);
            else
                x=ch[x][0]+ch[x][1];
            return ret;
        }
        return remove(ch[x][key[x]<k],k);
    }
    bool find(int x,int k) {
        while(x) {
            if(key[x]==k)
                return true;
            x=ch[x][key[x]<k];
        }
        return false;
    }
    void insert(int k) {
        if(!find(root,k))
            insert(root,k);
    }
    void remove(int k) {
        if(find(root,k))
            remove(root,k);
    }
    int getKth(int k) {
        int x=root;
        while(size[ch[x][0]]+1!=k)
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return key[x];
    }
    int getRank(int k) {
        int ret=0,x=root;
        while(x)
            if(k<key[x])
                x=ch[x][0];
            else {
                ret+=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        return ret;
    }
} sbt;
int main() {
    int n,num;
    char c;
    scanf("%d",&n);
    while(n--) {
        scanf(" %c%d",&c,&num);
        switch(c) {
        case 'I':
            sbt.insert(num);
            break;
        case 'D':
            sbt.remove(num);
            break;
        case 'K':
            num<=sbt.size[sbt.root]?printf("%d\n",sbt.getKth(num)):puts("invalid");
            break;
        case 'C':
            printf("%d\n",sbt.getRank(num-1));
            break;
        }
    }
}

  BZOJ1588

  难度一颗星;平衡树插入、求前驱、求后继。两种姿势Treap、两种姿势Size Balanced Tree各一发。

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=40005;
const int INF=0x3f3f3f3f;
struct Treap {
    int tot,root;
    int ch[MAXN][2],key[MAXN],pt[MAXN],cnt[MAXN],size[MAXN];
    Treap() {
        tot=root=0;
        pt[0]=INF;
        size[0]=0;
    }
    void update(int x) {
        size[x]=size[ch[x][0]]+cnt[x]+size[ch[x][1]];
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        update(x);
        update(y);
        x=y;
    }
    void insert(int &x,int k) {
        if(x) {
            if(key[x]==k)
                ++cnt[x];
            else {
                int t=key[x]<k;
                insert(ch[x][t],k);
                if(pt[ch[x][t]]<pt[x])
                    rotate(x,t);
            }
        } else {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            pt[x]=rand();
            cnt[x]=1;
        }
        update(x);
    }
    void insert(int k) {
        insert(root,k);
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k==key[x]&&cnt[x]>1)
            return x;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k==key[x]&&cnt[x]>1)
            return x;
        if(k<key[x])
            getNext(ch[x][0],x,k);
        else
            getNext(ch[x][1],y,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
    int sigma(int k) {
        int pre=getPre(k),next=getNext(k),ret=INF;
        if(pre)
            ret=min(ret,k-key[pre]);
        if(next)
            ret=min(ret,key[next]-k);
        return ret==INF?k:ret;
    }
};
int main() {
    int n,x;
    while(~scanf("%d",&n)) {
        Treap treap;
        int ans=0;
        while(n--) {
            if(!~scanf("%d",&x))
                x=0;
            treap.insert(x);
            ans+=treap.sigma(x);
        }
        printf("%d\n",ans);
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=40005;
const int INF=0x3f3f3f3f;
struct Treap {
    int tot,root;
    int ch[MAXN][2],key[MAXN],pt[MAXN],size[MAXN];
    Treap() {
        tot=root=0;
        pt[0]=INF;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    bool insert(int &x,int k) {
        if(!x) {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            pt[x]=rand();
            size[x]=1;
            return true;
        }
        if(key[x]==k)
            return false;
        int t=key[x]<k;
        if(!insert(ch[x][t],k))
            return false;
        ++size[x];
        if(pt[ch[x][t]]<pt[x])
            rotate(x,t);
        return true;
    }
    bool insert(int k) {
        return insert(root,k);
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k<key[x])
            return getNext(ch[x][0],x,k);
        else
            return getNext(ch[x][1],y,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
    int sigma(int k) {
        int pre=getPre(k),next=getNext(k),ret=INF;
        if(pre)
            ret=min(ret,k-key[pre]);
        if(next)
            ret=min(ret,key[next]-k);
        return ret==INF?k:ret;
    }
};
int main() {
    int n,x;
    while(~scanf("%d",&n)) {
        Treap treap;
        int ans=0;
        while(n--) {
            if(!~scanf("%d",&x))
                x=0;
            bool flag=treap.insert(x);
            ans+=flag?treap.sigma(x):0;
        }
        printf("%d\n",ans);
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=40005;
const int INF=0x3f3f3f3f;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN];
    SBT() {
        tot=root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        } else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    void insert(int &x,int k) {
        if(!x) {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            size[x]=1;
        } else {
            ++size[x];
            insert(ch[x][key[x]<k],k);
            Maintain(x,key[x]<k);
        }
    }
    bool find(int &x,int k) {
        if(!x)
            return false;
        if(key[x]==k)
            return true;
        return find(ch[x][key[x]<k],k);
    }
    int insert(int k) {
        bool flag=find(root,k);
        if(!flag)
            insert(root,k);
        return !flag;
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k<key[x])
            return getNext(ch[x][0],x,k);
        else
            return getNext(ch[x][1],y,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
    int sigma(int k) {
        int pre=getPre(k),next=getNext(k),ret=INF;
        if(pre)
            ret=min(ret,k-key[pre]);
        if(next)
            ret=min(ret,key[next]-k);
        return ret==INF?k:ret;
    }
};
int main() {
    int n,x;
    while(~scanf("%d",&n)) {
        SBT sbt;
        int ans=0;
        while(n--) {
            if(!~scanf("%d",&x))
                x=0;
            bool flag=sbt.insert(x);
            ans+=flag?sbt.sigma(x):0;
        }
        printf("%d\n",ans);
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=40005;
const int INF=0x3f3f3f3f;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN];
    SBT() {
        tot=root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        } else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    bool insert(int &x,int k) {
        if(!x) {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            size[x]=1;
            return true;
        }
        if(key[x]==k)
            return false;
        int t=key[x]<k;
        if(!insert(ch[x][t],k))
            return false;
        ++size[x];
        Maintain(x,t);
        return true;
    }
    bool insert(int k) {
        return insert(root,k);
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k<key[x])
            return getNext(ch[x][0],x,k);
        else
            return getNext(ch[x][1],y,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
    int sigma(int k) {
        int pre=getPre(k),next=getNext(k),ret=INF;
        if(pre)
            ret=min(ret,k-key[pre]);
        if(next)
            ret=min(ret,key[next]-k);
        return ret==INF?k:ret;
    }
};
int main() {
    int n,x;
    while(~scanf("%d",&n)) {
        SBT sbt;
        int ans=0;
        while(n--) {
            if(!~scanf("%d",&x))
                x=0;
            bool flag=sbt.insert(x);
            ans+=flag?sbt.sigma(x):0;
        }
        printf("%d\n",ans);
    }
}

  BZOJ1208

  难度一星半;平衡树插入、删除、求前驱、求后继。两种姿势Treap、两种姿势Size Balanced Tree各一发。

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=80005;
const int INF=0x7fffffff;
const int MOD=1000000;
struct Treap {
    int tot,root;
    int ch[MAXN][2],key[MAXN],pt[MAXN],cnt[MAXN],size[MAXN];
    Treap() {
        tot=root=0;
        pt[0]=INF;
        size[0]=0;
    }
    void update(int x) {
        size[x]=size[ch[x][0]]+cnt[x]+size[ch[x][1]];
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        update(x);
        update(y);
        x=y;
    }
    void insert(int &x,int k) {
        if(x) {
            if(key[x]==k)
                ++cnt[x];
            else {
                int t=key[x]<k;
                insert(ch[x][t],k);
                if(pt[ch[x][t]]<pt[x])
                    rotate(x,t);
            }
        } else {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            pt[x]=rand();
            cnt[x]=1;
        }
        update(x);
    }
    void erase(int &x,int k) {
        if(key[x]==k) {
            if(cnt[x]>1)
                --cnt[x];
            else {
                if(!ch[x][0]&&!ch[x][1]) {
                    x=0;
                    return;
                }
                rotate(x,pt[ch[x][0]]>pt[ch[x][1]]);
                erase(x,k);
            }
        } else
            erase(ch[x][key[x]<k],k);
        update(x);
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k<key[x])
            return getNext(ch[x][0],x,k);
        else
            return getNext(ch[x][1],y,k);
    }
    void insert(int k) {
        insert(root,k);
    }
    void erase(int k) {
        erase(root,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
};
int main() {
    int n,a,b;
    while(~scanf("%d",&n)) {
        Treap treap;
        int ans=0,status;
        while(n--) {
            scanf("%d%d",&a,&b);
            if(treap.size[treap.root]==0)
                status=a;
            treap.insert(b);
            if(status!=a) {
                int pre=treap.getPre(b),next=treap.getNext(b),pv=INF,nv=INF;
                if(pre)
                    pv=b-treap.key[pre];
                if(next)
                    nv=treap.key[next]-b;
                ans+=min(pv,nv);
                ans%=MOD;
                if(pv<=nv)
                    treap.erase(treap.key[pre]);
                else
                    treap.erase(treap.key[next]);
                treap.erase(b);
            }
        }
        printf("%d\n",ans);
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=80005;
const int INF=0x7fffffff;
const int MOD=1000000;
struct Treap {
    int tot,root;
    int ch[MAXN][2],key[MAXN],pt[MAXN],size[MAXN];
    Treap() {
        tot=root=0;
        pt[0]=INF;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    bool insert(int &x,int k) {
        if(!x) {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            pt[x]=rand();
            size[x]=1;
            return true;
        }
        if(key[x]==k)
            return false;
        int t=key[x]<k;
        if(!insert(ch[x][t],k))
            return false;
        ++size[x];
        if(pt[ch[x][t]]<pt[x])
            rotate(x,t);
        return true;
    }
    bool erase(int &x,int k) {
        if(!x)
            return false;
        if(key[x]!=k) {
            if(!erase(ch[x][key[x]<k],k))
                return false;
            --size[x];
        } else if(!ch[x][0]&&!ch[x][1])
            x=0;
        else if(!ch[x][0])
            x=ch[x][1];
        else if(!ch[x][1])
            x=ch[x][0];
        else {
            rotate(x,pt[ch[x][0]]>pt[ch[x][1]]);
            if(!erase(ch[x][key[x]<k],k))
                return false;
            --size[x];
        }
        return true;
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k<key[x])
            return getNext(ch[x][0],x,k);
        else
            return getNext(ch[x][1],y,k);
    }
    void insert(int k) {
        insert(root,k);
    }
    void erase(int k) {
        erase(root,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
};
int main() {
    int n,a,b;
    while(~scanf("%d",&n)) {
        Treap treap;
        int ans=0,status;
        while(n--) {
            scanf("%d%d",&a,&b);
            if(treap.size[treap.root]==0)
                status=a;
            treap.insert(b);
            if(status!=a) {
                int pre=treap.getPre(b),next=treap.getNext(b),pv=INF,nv=INF;
                if(pre)
                    pv=b-treap.key[pre];
                if(next)
                    nv=treap.key[next]-b;
                ans+=min(pv,nv);
                ans%=MOD;
                if(pv<=nv)
                    treap.erase(treap.key[pre]);
                else
                    treap.erase(treap.key[next]);
                treap.erase(b);
            }
        }
        printf("%d\n",ans);
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=80005;
const int INF=0x7fffffff;
const int MOD=1000000;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN];
    SBT() {
        tot=root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        } else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    void insert(int &x,int k) {
        if(!x) {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            size[x]=1;
        } else {
            ++size[x];
            insert(ch[x][key[x]<k],k);
            Maintain(x,key[x]<k);
        }
    }
    int erase(int &x,int k) {
        --size[x];
        if(key[x]==k||(key[x]>k&&ch[x][0]==0)||(key[x]<k&&ch[x][1]==0)) {
            int ret=key[x];
            if(ch[x][0]&&ch[x][1])
                key[x]=erase(ch[x][0],key[x]+1);
            else
                x=ch[x][0]+ch[x][1];
            return ret;
        }
        return erase(ch[x][key[x]<k],k);
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k<key[x])
            return getNext(ch[x][0],x,k);
        else
            return getNext(ch[x][1],y,k);
    }
    void insert(int k) {
        insert(root,k);
    }
    void erase(int k) {
        erase(root,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
};
int main() {
    int n,a,b;
    while(~scanf("%d",&n)) {
        SBT sbt;
        int ans=0,status;
        while(n--) {
            scanf("%d%d",&a,&b);
            if(sbt.size[sbt.root]==0)
                status=a;
            sbt.insert(b);
            if(status!=a) {
                int pre=sbt.getPre(b),next=sbt.getNext(b),pv=INF,nv=INF;
                if(pre)
                    pv=b-sbt.key[pre];
                if(next)
                    nv=sbt.key[next]-b;
                ans+=min(pv,nv);
                ans%=MOD;
                if(pv<=nv)
                    sbt.erase(sbt.key[pre]);
                else
                    sbt.erase(sbt.key[next]);
                sbt.erase(b);
            }
        }
        printf("%d\n",ans);
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=80005;
const int INF=0x7fffffff;
const int MOD=1000000;
struct SBT {
    int root,tot;
    int ch[MAXN][2],key[MAXN],size[MAXN];
    SBT() {
        tot=root=0;
        size[0]=0;
    }
    void rotate(int &x,int t) {
        int y=ch[x][t];
        ch[x][t]=ch[y][t^1];
        ch[y][t^1]=x;
        size[y]=size[x];
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        x=y;
    }
    void Maintain(int &x,int t) {
        if(size[ch[ch[x][t]][t]]>size[ch[x][t^1]])
            rotate(x,t);
        else if(size[ch[ch[x][t]][t^1]]>size[ch[x][t^1]]) {
            rotate(ch[x][t],t^1);
            rotate(x,t);
        } else
            return;
        Maintain(ch[x][0],0);
        Maintain(ch[x][1],1);
        Maintain(x,0);
        Maintain(x,1);
    }
    bool insert(int &x,int k) {
        if(!x) {
            x=++tot;
            ch[x][0]=ch[x][1]=0;
            key[x]=k;
            size[x]=1;
            return true;
        }
        if(key[x]==k)
            return false;
        int t=key[x]<k;
        if(!insert(ch[x][t],k))
            return false;
        ++size[x];
        Maintain(x,t);
        return true;
    }
    bool erase(int &x,int k) {
        if(!x)
            return false;
        int t;
        if(key[x]==k) {
            if(!ch[x][1]) {
                x=ch[x][0];
                return true;
            }
            if(!ch[x][0]) {
                x=ch[x][1];
                return true;
            }
            int r=ch[x][1];
            while(ch[r][0])
                r=ch[r][0];
            key[x]=key[r];
            erase(ch[x][1],key[r]);
            t=0;
        } else {
            t=k<key[x];
            erase(ch[x][t^1],k);
        }
        Maintain(x,t);
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
        return true;
    }
    int getPre(int x,int y,int k) {
        if(x==0)
            return y;
        if(k>key[x])
            return getPre(ch[x][1],x,k);
        else
            return getPre(ch[x][0],y,k);
    }
    int getNext(int x,int y,int k) {
        if(x==0)
            return y;
        if(k<key[x])
            return getNext(ch[x][0],x,k);
        else
            return getNext(ch[x][1],y,k);
    }
    void insert(int k) {
        insert(root,k);
    }
    void erase(int k) {
        erase(root,k);
    }
    int getPre(int k) {
        return getPre(root,0,k);
    }
    int getNext(int k) {
        return getNext(root,0,k);
    }
};
int main() {
    int n,a,b;
    while(~scanf("%d",&n)) {
        SBT sbt;
        int ans=0,status;
        while(n--) {
            scanf("%d%d",&a,&b);
            if(sbt.size[sbt.root]==0)
                status=a;
            sbt.insert(b);
            if(status!=a) {
                int pre=sbt.getPre(b),next=sbt.getNext(b),pv=INF,nv=INF;
                if(pre)
                    pv=b-sbt.key[pre];
                if(next)
                    nv=sbt.key[next]-b;
                ans+=min(pv,nv);
                ans%=MOD;
                if(pv<=nv)
                    sbt.erase(sbt.key[pre]);
                else
                    sbt.erase(sbt.key[next]);
                sbt.erase(b);
            }
        }
        printf("%d\n",ans);
    }
}

  HDU1890

  难度两颗星;区间翻转。两种姿势Splay各一发。

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=100005;
pair<int,int> p[MAXN];
struct Splay {
    int root;
    int ch[MAXN][2],pre[MAXN],size[MAXN];
    void rotate(int x,int f) {
        int y=pre[x];
        ch[y][f^1]=ch[x][f];
        pre[ch[x][f]]=y;
        pre[x]=pre[y];
        if(pre[x])
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        ch[x][f]=y;
        pre[y]=x;
        push_up(y);
    }
    void splay(int x,int goal) {
        push_down(x);
        while(pre[x]!=goal) {
            int y=pre[x],z=pre[y];
            if(z==goal) {
                push_down(y);
                push_down(x);
                rotate(x,ch[y][0]==x);
            } else {
                push_down(z);
                push_down(y);
                push_down(x);
                int f=ch[z][0]==y;
                if(ch[y][f]==x)
                    rotate(x,f^1);
                else
                    rotate(y,f);
                rotate(x,f);
            }
        }
        push_up(x);
        if(goal==0)
            root=x;
    }
    void rotate_to(int k,int goal) {
        int x=root;
        push_down(x);
        while(size[ch[x][0]]+1!=k) {
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
            push_down(x);
        }
        splay(x,goal);
    }
    void NewNode(int x,int fa) {
        ch[x][0]=ch[x][1]=0;
        size[x]=1;
        pre[x]=fa;
        rev[x]=0;
    }
    void push_up(int x) {
        size[x]=size[ch[x][0]]+1+size[ch[x][1]];
    }
    void push_down(int x) {
        if(rev[x]) {
            rev[ch[x][0]]^=1;
            rev[ch[x][1]]^=1;
            swap(ch[x][0],ch[x][1]);
            rev[x]=0;
        }
    }
    void build(int &x,int l,int r,int f) {
        if(l>r)
            return;
        int m=l+r>>1;
        x=m;
        NewNode(x,f);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        push_up(x);
    }
    void erase(int x) {
        int y=pre[x];
        if(!ch[x][0]) {
            ch[y][ch[y][1]==x]=ch[x][1];
            pre[ch[x][1]]=y;
        } else {
            int z=ch[x][0];
            push_down(z);
            while(ch[z][1]) {
                z=ch[z][1];
                push_down(z);
            }
            splay(z,y);
            ch[z][1]=ch[x][1];
            pre[ch[x][1]]=z;
            ch[y][ch[y][1]==x]=z;
            pre[z]=y;
        }
    }
    void init(int n) {
        root=0;
        ch[0][0]=ch[0][1]=pre[0]=size[0]=0;
        rev[0]=0;
        build(root,1,n,0);
    }
    void solve(int n) {
        init(n);
        for(int i=1; i<=n; ++i) {
            splay(p[i].second,0);
            if(i>1)
                putchar(' ');
            printf("%d",i+size[ch[root][0]]);
            rev[ch[root][0]]^=1;
            erase(root);
        }
        putchar('\n');
    }
    int rev[MAXN];
} splay;
int main() {
    int n;
    while(~scanf("%d",&n)&&n) {
        for(int i=1; i<=n; ++i) {
            scanf("%d",&p[i].first);
            p[i].second=i;
        }
        sort(p+1,p+n+1);
        splay.solve(n);
    }
}
#include<cstdio>
#include<algorithm>
using namespace std;
#define keyTree ch[ch[root][1]][0]
const int MAXN=100005;
pair<int,int> p[MAXN];
struct Splay {
    int root;
    int ch[MAXN][2],pre[MAXN],size[MAXN];
    void rotate(int x,int f) {
        int y=pre[x];
        ch[y][f^1]=ch[x][f];
        pre[ch[x][f]]=y;
        pre[x]=pre[y];
        if(pre[x])
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        ch[x][f]=y;
        pre[y]=x;
        push_up(y);
    }
    void splay(int x,int goal) {
        push_down(x);
        while(pre[x]!=goal) {
            int y=pre[x],z=pre[y];
            if(z==goal) {
                push_down(y);
                push_down(x);
                rotate(x,ch[y][0]==x);
            } else {
                push_down(z);
                push_down(y);
                push_down(x);
                int f=ch[z][0]==y;
                if(ch[y][f]==x)
                    rotate(x,f^1);
                else
                    rotate(y,f);
                rotate(x,f);
            }
        }
        push_up(x);
        if(goal==0)
            root=x;
    }
    void rotate_to(int k,int goal) {
        int x=root;
        push_down(x);
        while(size[ch[x][0]]+1!=k) {
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
            push_down(x);
        }
        splay(x,goal);
    }
    void NewNode(int &x,int fa) {
        ch[x][0]=ch[x][1]=0;
        size[x]=1;
        pre[x]=fa;
        rev[x]=0;
    }
    void push_up(int x) {
        size[x]=size[ch[x][0]]+1+size[ch[x][1]];
    }
    void push_down(int x) {
        if(rev[x]) {
            rev[ch[x][0]]^=1;
            rev[ch[x][1]]^=1;
            swap(ch[x][0],ch[x][1]);
            rev[x]=0;
        }
    }
    void build(int &x,int l,int r,int f) {
        if(l>r)
            return;
        int m=l+r>>1;
        x=m;
        NewNode(x,f);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        push_up(x);
    }
    void init(int n) {
        ch[0][0]=ch[0][1]=size[0]=0;
        rev[0]=0;
        root=n+1;
        NewNode(root,0);
        ch[root][1]=n+2;
        NewNode(ch[root][1],root);
        size[root]=2;
        build(keyTree,1,n,ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
    }
    int get_next(int x) {
        push_down(x);
        if(ch[x][1]==0)
            return -1;
        x=ch[x][1];
        while(ch[x][0]) {
            x=ch[x][0];
            push_down(x);
        }
        return x;
    }
    void solve(int n) {
        init(n);
        for(int i=1; i<=n; ++i) {
            splay(p[i].second,0);
            if(i>1)
                putchar(' ');
            printf("%d",size[ch[root][0]]);
            rotate_to(i,0);
            splay(get_next(p[i].second),root);
            rev[keyTree]^=1;
            push_up(ch[root][1]);
            push_up(root);
        }
        putchar('\n');
    }
    int rev[MAXN];
} splay;
int main() {
    int n;
    while(~scanf("%d",&n)&&n) {
        for(int i=1; i<=n; ++i) {
            scanf("%d",&p[i].first);
            p[i].second=i;
        }
        sort(p+1,p+n+1);
        splay.solve(n);
    }
}

  HDU3436

  难度两颗星;节点移动,平衡树求第k小,求排名。Splay一发。

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=100005;
char op[MAXN][10];
int data[MAXN],hash[MAXN],bg[MAXN<<1],ed[MAXN<<1],cnt;
int bi_search(int x) {
    int l=0,r=cnt-1;
    while(l<=r) {
        int m=l+r>>1;
        if(bg[m]<=x&&ed[m]>=x)
            return m;
        if(ed[m]<x)
            l=m+1;
        else
            r=m-1;
    }
}
struct SplayTree {
    int root,tot;
    int ch[MAXN<<1][2],pre[MAXN<<1],size[MAXN<<1];
    void rotate(int x,int f) {
        int y=pre[x];
        ch[y][f^1]=ch[x][f];
        pre[ch[x][f]]=y;
        pre[x]=pre[y];
        if(pre[x])
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        ch[x][f]=y;
        pre[y]=x;
        push_up(y);
    }
    void splay(int x,int goal) {
        while(pre[x]!=goal)
            if(pre[pre[x]]==goal)
                rotate(x,ch[pre[x]][0]==x);
            else {
                int y=pre[x],z=pre[y],f=ch[z][0]==y;
                if(ch[y][f]==x)
                    rotate(x,f^1);
                else
                    rotate(y,f);
                rotate(x,f);
            }
        push_up(x);
        if(goal==0)
            root=x;
    }
    void rotate_to(int k,int goal) {
        int x=root;
        while(size[ch[x][0]]+1!=k)
            if(k<size[ch[x][0]]+1)
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
        splay(x,goal);
    }
    void NewNode(int &x,int fa,int k) {
        x=++tot;
        ch[x][0]=ch[x][1]=0;
        size[x]=num[x]=ed[k]-bg[k]+1;
        pre[x]=fa;
        key[x]=k;
        node[k]=x;
    }
    void push_up(int x) {
        size[x]=size[ch[x][0]]+size[ch[x][1]]+num[x];
    }
    void build(int &x,int l,int r,int f) {
        if(l>r)
            return;
        int m=l+r>>1;
        NewNode(x,f,m);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        push_up(x);
    }
    void init() {
        root=tot=0;
        ch[0][0]=ch[0][1]=size[0]=0;
        build(root,0,cnt-1,0);
    }
    int get_rank(int x) {
        int k=bi_search(x);
        splay(node[k],0);
        return size[ch[root][0]]+1;
    }
    int get_kth(int x,int k) {
        int t=size[ch[x][0]];
        if(t>=k)
            return get_kth(ch[x][0],k);
        else if(t+num[x]>=k)
            return bg[key[x]]+k-t-1;
        else
            return get_kth(ch[x][1],k-t-num[x]);
    }
    void insert(int &x,int k,int fa) {
        if(x==0) {
            NewNode(x,fa,k);
            splay(x,0);
            return;
        }
        insert(ch[x][0],k,x);
        push_up(x);
    }
    void del() {
        int x=root;
        if(ch[root][1]) {
            root=ch[root][1];
            rotate_to(1,0);
            ch[root][0]=ch[x][0];
            if(ch[root][0])
                pre[ch[root][0]]=root;
        } else
            root=ch[root][0];
        pre[root]=0;
        push_up(root);
    }
    void top(int x) {
        int k=bi_search(x);
        splay(node[k],0);
        del();
        insert(root,k,0);
        splay(node[k],0);
    }
    int key[MAXN<<1],num[MAXN<<1],node[MAXN<<1];
} splay;
int main() {
    int t,n,q;
    scanf("%d",&t);
    for(int cas=1; cas<=t; ++cas) {
        scanf("%d%d",&n,&q);
        int tot=cnt=0;
        hash[tot++]=0;
        for(int i=0; i<q; ++i) {
            scanf("%s%d",op[i],&data[i]);
            if(op[i][0]!='R')
                hash[tot++]=data[i];
        }
        hash[tot++]=n;
        sort(hash,hash+tot);
        tot=unique(hash,hash+tot)-hash;
        for(int i=1; i<tot; ++i) {
            if(hash[i]-hash[i-1]>1) {
                bg[cnt]=hash[i-1]+1;
                ed[cnt]=hash[i]-1;
                ++cnt;
            }
            bg[cnt]=ed[cnt]=hash[i];
            ++cnt;
        }
        printf("Case %d:\n",cas);
        splay.init();
        for(int i=0; i<q; ++i)
            switch(op[i][0]) {
            case 'T':
                splay.top(data[i]);
                break;
            case 'Q':
                printf("%d\n",splay.get_rank(data[i]));
                break;
            case 'R':
                printf("%d\n",splay.get_kth(splay.root,data[i]));
                break;
            }
    }
}

  HDU3487

  难度两星半;区间分割(移动),区间翻转。Splay一发。

#include<cstdio>
#include<algorithm>
using namespace std;
#define keyTree (ch[ch[root][1]][0])
const int MAXN=300005;
struct SplayTree {
    int root,tot;
    int ch[MAXN][2],pre[MAXN],size[MAXN];
    void rotate(int x,int f) {
        int y=pre[x];
        ch[y][f^1]=ch[x][f];
        pre[ch[x][f]]=y;
        pre[x]=pre[y];
        if(pre[x])
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        ch[x][f]=y;
        pre[y]=x;
        push_up(y);
    }
    void splay(int x,int goal) {
        push_down(x);
        while(pre[x]!=goal) {
            int y=pre[x],z=pre[y];
            if(z==goal) {
                push_down(y);
                push_down(x);
                rotate(x,ch[y][0]==x);
            } else {
                push_down(z);
                push_down(y);
                push_down(x);
                int f=ch[z][0]==y;
                if(ch[y][f]==x)
                    rotate(x,f^1);
                else
                    rotate(y,f);
                rotate(x,f);
            }
        }
        push_up(x);
        if(goal==0)
            root=x;
    }
    void rotate_to(int k,int goal) {
        int x=root;
        push_down(x);
        while(size[ch[x][0]]!=k) {
            if(k<size[ch[x][0]])
                x=ch[x][0];
            else {
                k-=size[ch[x][0]]+1;
                x=ch[x][1];
            }
            push_down(x);
        }
        splay(x,goal);
    }
    void NewNode(int &x,int c,int fa) {
        x=++tot;
        ch[x][0]=ch[x][1]=0;
        size[x]=1;
        pre[x]=fa;
        key[x]=c;
        rev[x]=0;
    }
    void push_up(int x) {
        size[x]=1+size[ch[x][0]]+size[ch[x][1]];
    }
    void push_down(int x) {
        if(rev[x]) {
            rev[ch[x][0]]^=1;
            rev[ch[x][1]]^=1;
            swap(ch[x][0],ch[x][1]);
            rev[x]=0;
        }
    }
    void build(int &x,int l,int r,int f) {
        if(l>r)
            return;
        int m=l+r>>1;
        NewNode(x,m,f);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        push_up(x);
    }
    void init(int n) {
        root=tot=0;
        ch[0][0]=ch[0][1]=size[0]=0;
        rev[0]=0;
        NewNode(root,-1,0);
        NewNode(ch[root][1],-1,root);
        size[root]=2;
        build(keyTree,1,n,ch[root][1]);
        push_up(ch[root][1]);
        push_up(root);
    }
    void reverse(int l,int r) {
        rotate_to(l-1,0);
        rotate_to(r+1,root);
        rev[keyTree]^=1;
    }
    void cut(int l,int r,int p) {
        rotate_to(l-1,0);
        rotate_to(r+1,root);
        int tmp=keyTree;
        keyTree=0;
        push_up(ch[root][1]);
        push_up(root);
        rotate_to(p,0);
        rotate_to(p+1,root);
        keyTree=tmp;
        pre[keyTree]=ch[root][1];
        push_up(ch[root][1]);
        push_up(root);
    }
    void InOrder(int x) {
        if(!x)
            return;
        push_down(x);
        InOrder(ch[x][0]);
        if(key[x]!=-1) {
            if(cnt>1)
                putchar(' ');
            printf("%d" ,key[x]);
        }
        ++cnt;
        InOrder(ch[x][1]);
    }
    void output() {
        cnt=0;
        InOrder(root);
        putchar('\n');
    }
    int key[MAXN],rev[MAXN],cnt;
} splay;
int main() {
    int n,m,a,b,c;
    char op[5];
    while(~scanf("%d%d",&n,&m)&&~n&&~m) {
        splay.init(n);
        while(m--) {
            scanf("%s%d%d",op,&a,&b);
            switch(op[0]) {
            case 'C':
                scanf("%d",&c);
                splay.cut(a,b,c);
                break;
            case 'F':
                splay.reverse(a,b);
                break;
            }
        }
        splay.output();
    }
}

  ZOJ2112

  难度三星半;单点修改,区间第k小。树状数组+可持久化线段树(主席树)、两种姿势线段树+Treap各一发。

#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,ls[rt]
#define rson m+1,r,rs[rt]
const int MAXN=60005;
const int MAXM=2500005;
int t,n,m,size;
int ls[MAXM],rs[MAXM],cnt[MAXM],root[MAXN],tot;
void build(int l,int r,int &rt) {
    rt=tot++;
    cnt[rt]=0;
    if(l==r)
        return;
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
void update(int last,int p,int val,int l,int r,int &rt) {
    rt=tot++;
    ls[rt]=ls[last];
    rs[rt]=rs[last];
    cnt[rt]=cnt[last]+val;
    if(l==r)
        return;
    int m=(l+r)>>1;
    if(p<=m)
        update(ls[last],p,val,lson);
    else
        update(rs[last],p,val,rson);
}
int bit[MAXN],use[MAXN];
inline int lowbit(int x) {
    return x&-x;
}
void modify(int x,int p,int val) {
    for(int i=x; i<=n; i+=lowbit(i))
        update(bit[i],p,val,1,size,bit[i]);
}
int sum(int x) {
    int ret=0;
    for(int i=x; i>0; i-=lowbit(i))
        ret+=cnt[ls[use[i]]];
    return ret;
}
int query(int ss,int tt,int l,int r,int k) {
    for(int i=ss; i>0; i-=lowbit(i))
        use[i]=bit[i];
    for(int i=tt; i>0; i-=lowbit(i))
        use[i]=bit[i];
    int sr=root[ss],tr=root[tt];
    while(l<r) {
        int m=(l+r)>>1,tmp=sum(tt)-sum(ss)+cnt[ls[tr]]-cnt[ls[sr]];
        if(k<=tmp) {
            r=m;
            for(int i=ss; i>0; i-=lowbit(i))
                use[i]=ls[use[i]];
            for(int i=tt; i>0; i-=lowbit(i))
                use[i]=ls[use[i]];
            sr=ls[sr];
            tr=ls[tr];
        } else {
            l=m+1;
            k-=tmp;
            for(int i=ss; i>0; i-=lowbit(i))
                use[i]=rs[use[i]];
            for(int i=tt; i>0; i-=lowbit(i))
                use[i]=rs[use[i]];
            sr=rs[sr];
            tr=rs[tr];
        }
    }
    return l;
}
int num[MAXN],hash[MAXN],l[MAXN],r[MAXN],k[MAXN];
char op[MAXN];
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);
        size=0;
        for(int i=1; i<=n; ++i) {
            scanf("%d",&num[i]);
            hash[++size]=num[i];
        }
        for(int i=0; i<m; ++i) {
            scanf(" %c%d%d",&op[i],&l[i],&r[i]);
            switch(op[i]) {
            case 'Q':
                scanf("%d",&k[i]);
                break;
            case 'C':
                hash[++size]=r[i];
                break;
            }
        }
        sort(hash+1,hash+size+1);
        size=unique(hash+1,hash+size+1)-hash-1;
        for(int i=1; i<=n; ++i)
            num[i]=lower_bound(hash+1,hash+size+1,num[i])-hash;
        tot=0;
        build(1,size,root[0]);
        for(int i=1; i<=n; ++i)
            update(root[i-1],num[i],1,1,size,root[i]);
        for(int i=1; i<=n; ++i)
            bit[i]=root[0];
        for(int i=0; i<m; ++i)
            switch(op[i]) {
            case 'Q':
                printf("%d\n",hash[query(l[i]-1,r[i],1,size,k[i])]);
                break;
            case 'C':
                modify(l[i],num[l[i]],-1);
                num[l[i]]=lower_bound(hash+1,hash+size+1,r[i])-hash;
                modify(l[i],num[l[i]],1);
                break;
            }
    }
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=60005;
const int MAXM=900005;
const int INF=0x3f3f3f3f;
int ch[MAXM][2],key[MAXM],pt[MAXM],cnt[MAXM],size[MAXM],tot,root;
void init() {
    tot=root=0;
    pt[0]=-INF;
    size[0]=0;
}
void update(int x) {
    size[x]=size[ch[x][0]]+cnt[x]+size[ch[x][1]];
}
void rotate(int &x,int t) {
    int y=ch[x][t];
    ch[x][t]=ch[y][t^1];
    ch[y][t^1]=x;
    update(x);
    update(y);
    x=y;
}
void insert(int &x,int k) {
    if(x) {
        if(key[x]==k)
            ++cnt[x];
        else {
            int t=key[x]<k;
            insert(ch[x][t],k);
            if(pt[ch[x][t]]>pt[x])
                rotate(x,t);
        }
    } else {
        x=++tot;
        ch[x][0]=ch[x][1]=0;
        key[x]=k;
        pt[x]=rand();
        cnt[x]=1;
    }
    update(x);
}
void erase(int &x,int k) {
    if(key[x]==k) {
        if(cnt[x]>1)
            --cnt[x];
        else {
            if(!ch[x][0]&&!ch[x][1]) {
                x=0;
                return;
            }
            rotate(x,pt[ch[x][0]]<pt[ch[x][1]]);
            erase(x,k);
        }
    } else
        erase(ch[x][key[x]<k],k);
    update(x);
}
int seg[MAXN<<2];
int calc(int x,int k) {
    if(!x)
        return 0;
    if(k<key[x])
        return calc(ch[x][0],k);
    else
        return size[ch[x][0]]+cnt[x]+calc(ch[x][1],k);
}
void segins(int p,int val,int l,int r,int rt) {
    insert(seg[rt],val);
    if(l==r)
        return;
    int m=l+r>>1;
    if(p<=m)
        segins(p,val,lson);
    else
        segins(p,val,rson);
}
void segdel(int p,int val,int l,int r,int rt) {
    erase(seg[rt],val);
    if(l==r)
        return;
    int m=l+r>>1;
    if(p<=m)
        segdel(p,val,lson);
    else
        segdel(p,val,rson);
}
int query(int L,int R,int k,int l,int r,int rt) {
    if(l==r)
        return l;
    int m=l+r>>1,cnt=calc(seg[rt<<1],R)-calc(seg[rt<<1],L);
    if(k<=cnt)
        return query(L,R,k,lson);
    else
        return query(L,R,k-cnt,rson);
}
int num[MAXN],hash[MAXN],l[MAXN],r[MAXN],k[MAXN];
char op[MAXN];
int main() {
    int t,n,m;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);
        int hs=0;
        for(int i=1; i<=n; ++i) {
            scanf("%d",&num[i]);
            hash[++hs]=num[i];
        }
        for(int i=0; i<m; ++i) {
            scanf(" %c%d%d",&op[i],&l[i],&r[i]);
            switch(op[i]) {
            case 'Q':
                scanf("%d",&k[i]);
                break;
            case 'C':
                hash[++hs]=r[i];
                break;
            }
        }
        sort(hash+1,hash+hs+1);
        hs=unique(hash+1,hash+hs+1)-hash-1;
        init();
        memset(seg,0,sizeof(seg));
        for(int i=1; i<=n; ++i) {
            num[i]=lower_bound(hash+1,hash+hs+1,num[i])-hash;
            segins(num[i],i,1,hs,1);
        }
        for(int i=0; i<m; ++i)
            switch(op[i]) {
            case 'Q':
                printf("%d\n",hash[query(l[i]-1,r[i],k[i],1,hs,1)]);
                break;
            case 'C':
                segdel(num[l[i]],l[i],1,hs,1);
                num[l[i]]=lower_bound(hash+1,hash+hs+1,r[i])-hash;
                segins(num[l[i]],l[i],1,hs,1);
                break;
            }
    }
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN=60005;
const int MAXM=900005;
const int INF=0x3f3f3f3f;
int ch[MAXM][2],key[MAXM],pt[MAXM],size[MAXM],tot,root;
void init() {
    tot=root=0;
    pt[0]=INF;
    size[0]=0;
}
void rotate(int &x,int t) {
    int y=ch[x][t];
    ch[x][t]=ch[y][t^1];
    ch[y][t^1]=x;
    size[y]=size[x];
    size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
    x=y;
}
bool insert(int &x,int k) {
    if(!x) {
        x=++tot;
        ch[x][0]=ch[x][1]=0;
        key[x]=k;
        pt[x]=rand();
        size[x]=1;
        return true;
    }
    if(key[x]==k)
        return false;
    int t=key[x]<k;
    if(!insert(ch[x][t],k))
        return false;
    ++size[x];
    if(pt[ch[x][t]]<pt[x])
        rotate(x,t);
    return true;
}
bool erase(int &x,int k) {
    if(!x)
        return false;
    if(key[x]!=k) {
        if(!erase(ch[x][key[x]<k],k))
            return false;
        --size[x];
    } else if(!ch[x][0]&&!ch[x][1])
        x=0;
    else if(!ch[x][0])
        x=ch[x][1];
    else if(!ch[x][1])
        x=ch[x][0];
    else {
        rotate(x,pt[ch[x][0]]>pt[ch[x][1]]);
        if(!erase(ch[x][key[x]<k],k))
            return false;
        --size[x];
    }
    return true;
}
int seg[MAXN<<2];
int calc(int x,int k) {
    if(!x)
        return 0;
    if(k<key[x])
        return calc(ch[x][0],k);
    else
        return size[ch[x][0]]+1+calc(ch[x][1],k);
}
void segins(int p,int val,int l,int r,int rt) {
    insert(seg[rt],val);
    if(l==r)
        return;
    int m=l+r>>1;
    if(p<=m)
        segins(p,val,lson);
    else
        segins(p,val,rson);
}
void segdel(int p,int val,int l,int r,int rt) {
    erase(seg[rt],val);
    if(l==r)
        return;
    int m=l+r>>1;
    if(p<=m)
        segdel(p,val,lson);
    else
        segdel(p,val,rson);
}
int query(int L,int R,int k,int l,int r,int rt) {
    if(l==r)
        return l;
    int m=l+r>>1,cnt=calc(seg[rt<<1],R)-calc(seg[rt<<1],L);
    if(k<=cnt)
        return query(L,R,k,lson);
    else
        return query(L,R,k-cnt,rson);
}
int num[MAXN],hash[MAXN],l[MAXN],r[MAXN],k[MAXN];
char op[MAXN];
int main() {
    int t,n,m;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);
        int hs=0;
        for(int i=1; i<=n; ++i) {
            scanf("%d",&num[i]);
            hash[++hs]=num[i];
        }
        for(int i=0; i<m; ++i) {
            scanf(" %c%d%d",&op[i],&l[i],&r[i]);
            switch(op[i]) {
            case 'Q':
                scanf("%d",&k[i]);
                break;
            case 'C':
                hash[++hs]=r[i];
                break;
            }
        }
        sort(hash+1,hash+hs+1);
        hs=unique(hash+1,hash+hs+1)-hash-1;
        init();
        memset(seg,0,sizeof(seg));
        for(int i=1; i<=n; ++i) {
            num[i]=lower_bound(hash+1,hash+hs+1,num[i])-hash;
            segins(num[i],i,1,hs,1);
        }
        for(int i=0; i<m; ++i)
            switch(op[i]) {
            case 'Q':
                printf("%d\n",hash[query(l[i]-1,r[i],k[i],1,hs,1)]);
                break;
            case 'C':
                segdel(num[l[i]],l[i],1,hs,1);
                num[l[i]]=lower_bound(hash+1,hash+hs+1,r[i])-hash;
                segins(num[l[i]],l[i],1,hs,1);
                break;
            }
    }
}

  未完待续……

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值