【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         

 

posted on 2016-12-09 20:34  myx12345  阅读(...)  评论(...编辑  收藏

导航

统计