【BZOJ1901】Dynamic Rankings(树套树,树状数组,主席树)
题意:给定一个N个数的序列,要求维护一个数据结构支持以下两种操作:
1:将第X个数改成Y
2:查询第X到第Y个数里第K小的数是多少
n,m<=10000,a[i]<=10^9
思路:单点修改版本的主席树
对于没有修改的主席树,我们直接在对应的节点上每个点继承上个点的状态,再用链表创建logn个点来表示这个数对t数组的修改
而单点修改不可能把后面的前缀和都加上logn个点
所以就利用树状数组的思想
t是一个树状数组,里面的每个点都是一棵主席树
更改时没有区别
询问时最多可能有logn段区间相减
时间复杂度(Nlogn^2)
1 var t:array[0..4000000]of record 2 l,r,s:longint; 3 end; 4 a,b,root,hash,left,right,flag:array[0..40000]of longint; 5 d:array[1..40000,1..3]of longint; 6 n,m,i,j,q,u,cnt,la,lb,s,tmp:longint; 7 ch:string; 8 9 procedure swap(var x,y:longint); 10 var t:longint; 11 begin 12 t:=x; x:=y; y:=t; 13 end; 14 15 function find(k:longint):longint; 16 var l,r,mid:longint; 17 begin 18 l:=1; r:=u; 19 while l<=r do 20 begin 21 mid:=(l+r)>>1; 22 if hash[mid]=k then exit(mid); 23 if hash[mid]<k then l:=mid+1 24 else r:=mid-1; 25 end; 26 end; 27 28 procedure qsort(l,r:longint); 29 var i,j,mid:longint; 30 begin 31 i:=l; j:=r; mid:=b[(l+r)>>1]; 32 repeat 33 while mid>b[i] do inc(i); 34 while mid<b[j] do dec(j); 35 if i<=j then 36 begin 37 swap(b[i],b[j]); 38 inc(i); dec(j); 39 end; 40 until i>j; 41 if l<j then qsort(l,j); 42 if i<r then qsort(i,r); 43 end; 44 45 function lowbit(x:longint):longint; 46 begin 47 exit(x and (-x)); 48 end; 49 50 51 procedure update(l,r:longint;var p:longint;v,x:longint); 52 var mid:longint; 53 begin 54 inc(cnt); t[cnt]:=t[p]; 55 p:=cnt; t[p].s:=t[p].s+x; 56 if l=r then exit; 57 mid:=(l+r)>>1; 58 if v<=mid then update(l,mid,t[p].l,v,x) 59 else update(mid+1,r,t[p].r,v,x); 60 end; 61 62 function query(l,r,k:longint):longint; 63 var s1,s2,i,mid:longint; 64 begin 65 if l=r then exit(l); 66 s1:=0; s2:=0; 67 for i:=1 to la do s1:=s1+t[t[left[i]].l].s; 68 for i:=1 to lb do s2:=s2+t[t[right[i]].l].s; 69 mid:=(l+r)>>1; 70 if s2-s1>=k then 71 begin 72 for i:=1 to la do left[i]:=t[left[i]].l; 73 for i:=1 to lb do right[i]:=t[right[i]].l; 74 exit(query(l,mid,k)); 75 end 76 else 77 begin 78 for i:=1 to la do left[i]:=t[left[i]].r; 79 for i:=1 to lb do right[i]:=t[right[i]].r; 80 exit(query(mid+1,r,k-(s2-s1))); 81 end; 82 end; 83 84 85 begin 86 assign(input,'data.in'); reset(input); 87 assign(output,'bzoj1901.out'); rewrite(output); 88 readln(n,m); 89 q:=0; 90 for i:=1 to n do 91 begin 92 read(a[i]); 93 inc(q); b[q]:=a[i]; 94 end; 95 readln; 96 for i:=1 to m do 97 begin 98 readln(ch); s:=0; 99 if ch[1]='C' then 100 begin 101 inc(q); 102 for j:=3 to length(ch) do 103 begin 104 if ch[j]=' ' then begin inc(s); continue; end; 105 d[i,s+1]:=d[i,s+1]*10+ord(ch[j])-ord('0'); 106 end; 107 b[q]:=d[i,2]; 108 end; 109 if ch[1]='Q' then 110 begin 111 flag[i]:=1; 112 for j:=3 to length(ch) do 113 begin 114 if ch[j]=' ' then begin inc(s); continue; end; 115 d[i,s+1]:=d[i,s+1]*10+ord(ch[j])-ord('0'); 116 end; 117 end; 118 end; 119 qsort(1,q); 120 hash[1]:=b[1]; u:=1; 121 for i:=2 to q do 122 if b[i]<>b[i-1] then begin inc(u); hash[u]:=b[i]; end; 123 124 for i:=1 to n do 125 begin 126 tmp:=find(a[i]); 127 j:=i; 128 while j<=n do 129 begin 130 update(1,u,root[j],tmp,1); 131 j:=j+lowbit(j); 132 end; 133 end; 134 135 for i:=1 to m do 136 if flag[i]=1 then 137 begin 138 la:=0; lb:=0; j:=d[i,1]-1; 139 while j>0 do 140 begin 141 inc(la); left[la]:=root[j]; 142 j:=j-lowbit(j); 143 end; 144 j:=d[i,2]; 145 while j>0 do 146 begin 147 inc(lb); right[lb]:=root[j]; 148 j:=j-lowbit(j); 149 end; 150 writeln(hash[query(1,u,d[i,3])]); 151 end 152 else 153 begin 154 tmp:=find(a[d[i,1]]); 155 j:=d[i,1]; 156 while j<=n do 157 begin 158 update(1,u,root[j],tmp,-1); 159 j:=j+lowbit(j); 160 end; 161 tmp:=find(d[i,2]); 162 j:=d[i,1]; 163 while j<=n do 164 begin 165 update(1,u,root[j],tmp,1); 166 j:=j+lowbit(j); 167 end; 168 a[d[i,1]]:=d[i,2]; 169 end; 170 close(input); 171 close(output); 172 end. 173 174 175 176
UPD(2018.9.21):C++
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 3100000 21 #define M 30000 22 #define MOD 1000000007 23 #define eps 1e-8 24 #define pi acos(-1) 25 #define oo 1e9 26 27 char ch[10]; 28 struct arr 29 { 30 int l,r,s; 31 }t[N]; 32 int a[M],b[M],root[M], 33 L[30],R[30],A[M],B[M],K[M],flag[M], 34 n,m,cnt,l1,l2,mx; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 int lowbit(int x) 46 { 47 return x&(-x); 48 } 49 50 int lsh(int x) 51 { 52 int l=1; 53 int r=mx; 54 while(l<=r) 55 { 56 int mid=(l+r)>>1; 57 if(b[mid]==x) return mid; 58 if(b[mid]<x) l=mid+1; 59 else r=mid-1; 60 } 61 } 62 63 64 void update(int l,int r,int x,int v,int &p) 65 { 66 t[++cnt].l=t[p].l; 67 t[cnt].r=t[p].r; 68 t[cnt].s=t[p].s; 69 p=cnt; 70 t[p].s+=v; 71 if(l==r) return; 72 int mid=(l+r)>>1; 73 if(x<=mid) update(l,mid,x,v,t[p].l); 74 else update(mid+1,r,x,v,t[p].r); 75 } 76 77 int query(int l,int r,int k) 78 { 79 //printf("%d %d %d ",l,r,k); 80 if(l==r) return l; 81 int s1=0; 82 int s2=0; 83 for(int i=1;i<=l1;i++) s1+=t[t[L[i]].l].s; 84 for(int i=1;i<=l2;i++) s2+=t[t[R[i]].l].s; 85 int tmp=s2-s1; 86 //printf("%d\n",tmp); 87 int mid=(l+r)>>1; 88 if(tmp>=k) 89 { 90 for(int i=1;i<=l1;i++) L[i]=t[L[i]].l; 91 for(int i=1;i<=l2;i++) R[i]=t[R[i]].l; 92 return query(l,mid,k); 93 } 94 else 95 { 96 for(int i=1;i<=l1;i++) L[i]=t[L[i]].r; 97 for(int i=1;i<=l2;i++) R[i]=t[R[i]].r; 98 return query(mid+1,r,k-tmp); 99 } 100 } 101 102 103 int main() 104 { 105 freopen("data.in","r",stdin); 106 freopen("bzoj1901.out","w",stdout); 107 int q; 108 scanf("%d%d",&n,&q); 109 m=0; 110 for(int i=1;i<=n;i++) 111 { 112 scanf("%d",&a[i]); 113 b[++m]=a[i]; 114 } 115 for(int i=1;i<=q;i++) 116 { 117 scanf("%s",ch); 118 scanf("%d%d",&A[i],&B[i]); 119 if(ch[0]=='Q'){scanf("%d",&K[i]); flag[i]=1;} 120 else b[++m]=B[i]; 121 } 122 sort(b+1,b+m+1); 123 cnt=0; 124 mx=1; 125 for(int i=2;i<=m;i++) 126 if(b[i]!=b[mx]) b[++mx]=b[i]; 127 for(int i=1;i<=n;i++) 128 { 129 int tmp=lsh(a[i]); 130 int j=i; 131 while(j<=n) 132 { 133 update(1,mx,tmp,1,root[j]); 134 j+=lowbit(j); 135 } 136 } 137 138 for(int i=1;i<=q;i++) 139 if(flag[i]) 140 { 141 l1=0; l2=0; A[i]--; 142 int j=A[i]; 143 while(j) 144 { 145 L[++l1]=root[j]; 146 j-=lowbit(j); 147 } 148 j=B[i]; 149 while(j) 150 { 151 R[++l2]=root[j]; 152 j-=lowbit(j); 153 } 154 printf("%d\n",b[query(1,mx,K[i])]); 155 } 156 else 157 { 158 int x=lsh(a[A[i]]); 159 int j=A[i]; 160 while(j<=n) 161 { 162 update(1,mx,x,-1,root[j]); 163 j+=lowbit(j); 164 } 165 a[A[i]]=B[i]; 166 x=lsh(B[i]); 167 j=A[i]; 168 while(j<=n) 169 { 170 update(1,mx,x,1,root[j]); 171 j+=lowbit(j); 172 } 173 } 174 175 176 } 177 178 179 180
null