一些数据结构题目的代码片段
来源:互联网 发布:linux 查看文件夹用户 编辑:程序博客网 时间:2024/06/06 08:26
自从暑假洗心革面怒艹数据结构以来,从我手中通过的题,其代码量就基本没低于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|1const 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|1const 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|1const 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|1const 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|1const 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|1const 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)+3const 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|1const 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|1int 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|1int 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|1int 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|1const 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|1const 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; } }}
未完待续……
- 一些数据结构题目的代码片段
- 一些有用的代码片段
- zend 一些常用的代码片段
- android一些很有用的代码片段
- Android一些很有用的代码片段
- 一些实用的jQuery代码片段
- 一些实用的jQuery代码片段
- 一些有关图像处理的代码片段
- Andorid中一些重要的代码片段
- 一些实用的JQuery代码片段收集
- 一些实用的jQuery代码片段
- HashTable & HashMap 的一些代码片段
- 【Matlab】关于Matlab的一些代码片段
- jdbc AbstractDao的一些代码片段
- 一些很有用的 PHP 代码片段
- 一些有意思的java代码片段
- wxWidgets一些代码片段
- ios一些代码片段
- 临时解决浏览器兼容性问题
- jquery $(document).ready() 与window.onload的区别
- gcc hello.c -lpthread
- Hadoop1.0存在的问题和Hadoop2.0的介绍
- 关于android:typeface
- 一些数据结构题目的代码片段
- MFC中创建列表框&&及添加表格的方法
- OC基础知识点的总结(全),学习OC的日记
- linux usb枚举过程分析
- 关于韦东山书上的裸机程序在mini2440上的运行
- MATLAB无法打开.m文件(恢复默认路径)
- JNI问题:findLibrary returned null
- 帕那索斯博士的奇幻秀
- 450C - Jzzhu and Chocolate