zoj 2112 Dynamic Rankings
区间第k大问题,因为这个是动态的,有修改,所以划分树是搞不定的。
第一次写树套树,也就是线段树套平衡树,线段树的每个节点是一个平衡树。
查询的时候二分枚举答案,然后判断当前枚举的数是不是第k大的。
这里我的平衡树选择的是treap,但是释放空间那儿写的好丑。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int inf=~0u>>1; 6 const int N=(int)1e5+10; 7 const int maxn=(int)1e9+1; 8 #define lson l,m,n<<1 9 #define rson m+1,r,n<<1|1 10 int x[N]; 11 struct Treap{ 12 struct node{ 13 node *ch[2]; 14 int v,p,sz; 15 node(int _v,node *n): 16 v(_v){ch[0]=ch[1]=n;p=rand();sz=1;} 17 void update(){sz=ch[0]->sz+ch[1]->sz+1;} 18 }; 19 node *root,*null; 20 Treap(){ 21 } 22 void init(){ 23 null=new node(0,0);null->sz=0;null->p=inf; 24 null->ch[0]=null->ch[1]=null; 25 root=null; 26 } 27 void rotate(node *&t,bool d){ 28 node *_t=t->ch[d]; 29 t->ch[d]=_t->ch[!d]; 30 _t->ch[!d]=t; 31 _t->update(); 32 t->update(); 33 t=_t; 34 } 35 void __insert(node *&t,int val){ 36 if(t==null){ 37 t=new node(val,null); 38 return; 39 } 40 bool d=val > t->v; 41 __insert(t->ch[d],val); 42 if(t->ch[d]->p < t->p)rotate(t,d); 43 t->update(); 44 } 45 void __del(node *&t,int val){ 46 if(t==null)return; 47 if(val == t->v){ 48 bool d = t->ch[1]->p < t->ch[0]->p; 49 if(t->ch[d]==null){ 50 delete t; 51 t=null; 52 return; 53 } 54 rotate(t,d); 55 __del(t->ch[!d],val); 56 }else{ 57 bool d=val > t->v; 58 __del(t->ch[d],val); 59 } 60 t->update(); 61 } 62 int __rank(node *t,int val){ 63 if(t==null)return 0; 64 int num=t->ch[0]->sz; 65 if(val< t->v)return __rank(t->ch[0],val); 66 return num+1+__rank(t->ch[1],val); 67 } 68 void __show(node *x){ 69 if(x==null)return; 70 __show(x->ch[0]); 71 printf("%d ",x->v); 72 __show(x->ch[1]); 73 } 74 void insert(int val){ 75 __insert(root,val); 76 } 77 void del(int val){ 78 __del(root,val); 79 } 80 int rank(int val){ 81 return __rank(root,val); 82 } 83 void show(){ 84 __show(root); 85 puts(""); 86 } 87 void __fre(node *t){ 88 if(t==null)return; 89 __fre(t->ch[0]); 90 __fre(t->ch[1]); 91 delete t; 92 } 93 void fre(){ 94 __fre(root); 95 } 96 }; 97 struct segtree{ 98 Treap s[N<<2]; 99 void build(int l,int r,int n){ 100 s[n].init(); 101 for(int i=l;i<=r;i++) 102 s[n].insert(x[i]); 103 if(l==r)return; 104 int m=(l+r)>>1; 105 build(lson); 106 build(rson); 107 } 108 void del(int l,int r,int n){ 109 s[n].fre(); 110 if(l==r)return; 111 int m=(l+r)>>1; 112 del(lson); 113 del(rson); 114 } 115 void update(int nn,int a,int l,int r,int n){ 116 s[n].del(x[nn]); 117 s[n].insert(a); 118 if(l==r)return; 119 int m=(l+r)>>1; 120 if(nn<=m)update(nn,a,lson); 121 else update(nn,a,rson); 122 } 123 int query(int ll,int rr,int val,int l,int r,int n){ 124 if(ll==l&&rr==r){ 125 return s[n].rank(val); 126 } 127 int m=(l+r)>>1; 128 if(rr<=m)return query(ll,rr,val,lson); 129 else if(ll>m)return query(ll,rr,val,rson); 130 else return query(ll,m,val,lson)+query(m+1,rr,val,rson); 131 } 132 }; 133 segtree T; 134 int n; 135 int check(int L,int R,int val,int k){ 136 int a=T.query(L,R,val-1,1,n,1); 137 int b=T.query(L,R,val,1,n,1); 138 if(k>a&&k<=b)return 1; 139 if(k<=a)return 0; 140 if(k>b)return -1; 141 } 142 int bs(int l,int r,int L,int R,int k){ 143 while(l<=r){ 144 int m=(l+r)>>1; 145 int res=check(L,R,m,k); 146 if(res==1)return m; 147 else if(res==-1)l=m+1; 148 else r=m-1; 149 } 150 } 151 int main(){ 152 int cas; 153 scanf("%d",&cas); 154 int m; 155 char op[5]; 156 int l,r,k; 157 while(cas--){ 158 scanf("%d%d",&n,&m); 159 for(int i=1;i<=n;i++)scanf("%d",&x[i]); 160 T.build(1,n,1); 161 162 while(m--){ 163 scanf("%s",op); 164 if(op[0]=='Q'){ 165 scanf("%d%d%d",&l,&r,&k); 166 int ans=bs(0,maxn,l,r,k); 167 printf("%d\n",ans); 168 }else{ 169 scanf("%d%d",&l,&r); 170 T.update(l,r,1,n,1); 171 x[l]=r; 172 } 173 } 174 T.del(1,n,1); 175 } 176 return 0; 177 }