1. 程式人生 > >P2617 Dynamic Rankings(主席樹+樹狀數組)

P2617 Dynamic Rankings(主席樹+樹狀數組)

數組 fine b+ efi 回憶 chang ++ 們的 chan

怕是還沒有題解,所以先寫一篇。

這題就是維護帶修改的主席樹。首先樹套樹肯定是能做的,既然樹套樹能做那麽整體二分肯定也是可以的。

由於我並沒有使用這兩種做法,所以此處不予介紹。

大概描述下主席樹的思路:

首先說說怎麽搞帶修改主席樹?

回憶一般的kth問題,我們的主席樹求的是前綴和,這樣我們在目標區間的左右端點的主席樹差分下就能求出kth。

那麽我們如何支持修改操作?

考慮到我們之前使用主席樹樸素的維護區間前綴和,支持修改的話,只要把前綴和交給擅長它的樹狀數組維護,主席樹只要維護下位置就好。




 1 #include"bits/stdc++.h"
 2 using namespace
std; 3 #define nn 40000000 4 #define lowbit(x) ((x)&(-x)) 5 6 int rt[nn],b[nn],a[nn],ca[nn],cb[nn],cc[nn] ; 7 int size[nn],xx[nn],yy[nn],l[nn],r[nn]; 8 int n,m; 9 int totn; 10 int tot,totx,toty; 11 12 inline int read(){ 13 int f=1,x=0;char ch; 14 do{ch=getchar();if(ch==-)f=-1;}while
(ch<0||ch>9); 15 do{x=x*10+ch-0;ch=getchar();}while(ch>=0&&ch<=9); 16 return f*x; 17 } 18 19 20 void change(int &y,int x,int L,int R,int pos,int v) 21 { 22 y=++tot; size[tot]=size[x]+v,l[tot]=l[x],r[tot]=r[x]; 23 if (L==R)return ; 24 int mid = R+L>>1
;if (pos<=mid)change(l[tot],l[x],L,mid,pos,v); 25 else change(r[tot],r[x],mid+1,R,pos,v); 26 } 27 28 inline void add(int x,int v) 29 { 30 int k = lower_bound(b+1,b+1+totn,a[x])-b; 31 for (int i=x;i<=n;i+=lowbit(i)) change(rt[i],rt[i],1,totn,k,v); 32 } 33 34 int query(int L,int R,int p) 35 { 36 if (L==R)return R; int sum=0; int mid = L+R>>1; 37 for (int i=1;i<=totx;i++)sum-=size[l[xx[i]]]; 38 for (int i=1;i<=toty;i++)sum+=size[l[yy[i]]]; 39 if (p<=sum) 40 { 41 for ( int i=1;i<=totx;i++)xx[i]=l[xx[i]]; 42 for ( int i=1;i<=toty;i++)yy[i]=l[yy[i]]; 43 return query(L,mid,p); 44 } 45 for ( int i=1;i<=totx;i++)xx[i]=r[xx[i]]; 46 for ( int i=1;i<=toty;i++)yy[i]=r[yy[i]]; 47 return query(mid+1,R,p-sum); 48 } 49 50 int main() 51 { char s; 52 n=read(),m=read(); 53 for (int i=1;i<=n;i++)a[i]=read(),b[++totn]=a[i]; 54 55 for (int i=1;i<=m;i++) 56 { 57 cin>>s; if (s==Q) ca[i]=read(),cb[i]=read(),cc[i]=read(); 58 else ca[i]=read(),cb[i]=read(),b[++totn]=cb[i]; 59 } 60 sort(b+1,b+1+totn); 61 totn=unique(b+1,b+1+totn)-b-1; 62 63 for ( int i=1;i<=n;i++) add(i,1); 64 for ( int i=1;i<=m;i++) 65 { 66 if (cc[i]) 67 { totx=toty=0; 68 for ( int j=ca[i]-1;j;j-=lowbit(j))xx[++totx]=rt[j]; 69 for ( int j=cb[i];j;j-=lowbit(j))yy[++toty]=rt[j]; 70 printf("%d\n",b[query(1,totn,cc[i])]); 71 } 72 else 73 { 74 add(ca[i],-1),a[ca[i]]=cb[i],add(ca[i],1); 75 } 76 } 77 78 }

P2617 Dynamic Rankings(主席樹+樹狀數組)