P1279 文艺平衡树
额真的是平衡树啊…调了0.5h有点方
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <vector> #include <limits> #include <set> #include <map> using namespace std; #define SZ 666666 int ch[SZ][2],fa[SZ],sz[SZ],val[SZ],an,root; bool rev[SZ]; void init() { root=1; ch[1][0]=0; ch[1][1]=2; sz[1]=2; fa[2]=1; ch[2][0]=ch[2][1]=0; sz[2]=1; an=2; } void pd(int x) { if(!rev[x]) return; swap(ch[x][0],ch[x][1]); rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; rev[x]=0; } void upd(int x) { sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; } void rot(int x) { int y=fa[x],d=ch[y][0]==x; pd(y); pd(x); int f=fa[y]; fa[x]=f; fa[y]=x; if(f) ch[f][ch[f][1]==y]=x; int p=ch[x][d]; ch[x][d]=y; ch[y][!d]=p; if(p) fa[p]=y; upd(y); upd(x); if(y==root) root=x; } void splay(int x,int f) { pd(x); while(fa[x]!=f) { int y=fa[x]; if(fa[y]!=f) { if(ch[fa[y]][1]==y^ch[y][0]==x) rot(x); else rot(y); } rot(x); } upd(x); if(!f) root=x; } void splayp(int x,int f) { int c=root; while(pd(c),sz[ch[c][0]]!=x-1) { if(sz[ch[c][0]]<x-1) x-=sz[ch[c][0]]+1,c=ch[c][1]; else c=ch[c][0]; } splay(c,f); } int n; #define RRL ch[ch[root][1]][0] void addnode(int& x,int f,int v) { x=++an; fa[x]=f; sz[x]=1; val[x]=v; ch[x][0]=ch[x][1]=rev[x]=0; } void build(int& x,int f,int l,int r) { if(l>r) {x=0; return;} int mid=l+r>>1; addnode(x,f,mid); build(ch[x][0],x,l,mid-1); build(ch[x][1],x,mid+1,r); upd(x); } void revs(int l,int r) { splayp(l,0); splayp(r+2,root); rev[RRL]^=1; } void prt(int cur) { if(!cur) return; pd(cur); prt(ch[cur][0]); if(val[cur]) printf("%d ",val[cur]); prt(ch[cur][1]); } int main() { int q; scanf("%d%d",&n,&q); init(); build(RRL,ch[root][1],1,n); upd(ch[root][1]); upd(root); while(q--) { int l,r; scanf("%d%d",&l,&r); revs(l,r); } prt(root); }
FJOI2016 神秘数
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <vector> #include <limits> #include <set> #include <map> using namespace std; #define SZ 666666 #define S2 5555555 int ch[S2][2],rot[SZ],sum[S2],an=0; void ins(int r1,int& r2,int l,int r,int p,int q) { if(!r2) r2=++an; sum[r2]=sum[r1]+q; if(l==r) return; int mid=l+r>>1; if(p<=mid) ins(ch[r1][0],ch[r2][0],l,mid,p,q), ch[r2][1]=ch[r1][1]; else ins(ch[r1][1],ch[r2][1],mid+1,r,p,q), ch[r2][0]=ch[r1][0]; } int query(int r1,int r2,int l,int r,int p) { if(l>p) return 0; if(sum[r1]==sum[r2]) return 0; if(r<=p) return sum[r2]-sum[r1]; int mid=l+r>>1,ans=0; ans+=query(ch[r1][0],ch[r2][0],l,mid,min(p,mid)); if(p>mid) ans+=query(ch[r1][1],ch[r2][1],mid+1,r,p); return ans; } int n,q,a[SZ],mm=1; int ans(int l,int r) { int cur=0; while(1) { int cc=query(rot[l-1],rot[r],1,mm,cur+1); if(cc==cur) return cc+1; cur=cc; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i), mm=max(mm,a[i]); for(int i=1;i<=n;i++) ins(rot[i-1],rot[i],1,mm,a[i],a[i]); scanf("%d",&q); while(q--) { int l,r; scanf("%d%d",&l,&r); printf("%d ",ans(l,r)); } }
bzoj3110 K大数查询
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <vector> #include <limits> #include <set> #include <map> using namespace std; #define SZ 23333333 int an=0,rot[SZ],sum[SZ],tag[SZ],ch[SZ][2],n; int alc(int& x) {return (x)?(x):(x=++an);} void I_add(int x,int l,int r,int ql,int qr) { sum[x]+=qr-ql+1; if(l==ql&&r==qr) {++tag[x]; return;} int mid=l+r>>1; if(ql<=min(mid,qr)) I_add(alc(ch[x][0]),l,mid,ql,min(mid,qr)); if(max(mid+1,ql)<=qr) I_add(alc(ch[x][1]),mid+1,r,max(mid+1,ql),qr); } void O_add(int x,int l,int r,int ql,int qr,int p) { I_add(alc(rot[x]),1,n,ql,qr); if(l==r) return; int mid=l+r>>1; if(p<=mid) O_add(x+x,l,mid,ql,qr,p); else O_add(x+x+1,mid+1,r,ql,qr,p); } int I_sum(int x,int l,int r,int ql,int qr) { if(!x||ql>qr) return 0; if(l==ql&&r==qr) return sum[x]; int mid=l+r>>1; return tag[x]*(qr-ql+1)+I_sum(ch[x][0],l,mid,ql,min(qr,mid))+I_sum(ch[x][1],mid+1,r,max(ql,mid+1),qr); } int O_query(int x,int l,int r,int ql,int qr,int p) { if(l==r) return l; int mid=l+r>>1,cnt=I_sum(rot[x+x+1],1,n,ql,qr); if(cnt>=p) return O_query(x+x+1,mid+1,r,ql,qr,p); else return O_query(x+x,l,mid,ql,qr,p-cnt); } int main() { int q; scanf("%d%d",&n,&q); while(q--) { int t,a,b,c; scanf("%d%d%d%d",&t,&a,&b,&c); if(t==1) O_add(1,1,n,a,b,c); else printf("%d ",O_query(1,1,n,a,b,c)); } }
时间关系就写到这里…碎觉