zoj 2112 动态区间求第k大

 题目大意:

动态单点更新,然后多次询问求区间内第k大

这里单个的主席树不能实现,这里采取的是树状数组套主席树

首先可以想的是将静态主席树先构建好,不去动它,这里空间复杂度就是O(nlogn),这个只要之前做过主席树的入门题的话就都不是问题

然后考虑更新的情况,这里将更新产生的前缀变化保存在树状数组中,那么每次更新都要更新logn棵树状数组上的主席树,每一棵的更新操作都是

logn次的,那么时间复杂度就是nlognlogn的只是可以承受的

之后的询问也是,预处理好用到的树状数组,然后保存到向量中,不断处理更新的值

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 #define N 120010
  5 #define lowbit(x) x&(-x)
  6 #define define_m int m=(l+r)>>1
  7 #define LS(x) node[x].ls
  8 #define RS(x) node[x].rs
  9 
 10 vector<int> v1,v2;
 11 
 12 struct Node{
 13     int ls , rs , sz;
 14     Node(int ls=0 , int rs=0 , int sz=0):ls(ls),rs(rs),sz(sz){}
 15     void init(){ls=rs=sz=0;}
 16 }node[N*20];
 17 int tot , T1[N] , T2[N] , n , m , val[N]; //T1表示普通节点上的静态主席树,T2表示树状数组上的前缀树
 18 int op[N] , s[N] , t[N] , rank[N];
 19 
 20 int Hash(int v){return lower_bound(val , val+n , v)-val+1;}
 21 
 22 int build(int l , int r)
 23 {
 24     int u = tot++;
 25     node[u].init();
 26     define_m;
 27     if(l!=r){
 28         LS(u) = build(l , m);
 29         RS(u) = build(m+1 , r);
 30     }
 31     return u;
 32 }
 33 
 34 void build(int o1 , int o2 , int l , int r , int pos , int v , int i)
 35 {
 36     if(l==r){
 37         node[o2].sz = node[o1].sz+v;
 38         return;
 39     }
 40     define_m;
 41     node[tot].init();
 42     if(m>=pos){
 43         LS(o2) = tot++ , RS(o2) = RS(o1);
 44         build(LS(o1) , LS(o2) , l , m , pos , v , i);
 45     }else{
 46         LS(o2) = LS(o1) , RS(o2) = tot++;
 47         build(RS(o1) , RS(o2) , m+1 , r , pos , v , i);
 48     }
 49     node[o2].sz = node[LS(o2)].sz+node[RS(o2)].sz;
 50    // cout<<"build : "<<i<<" "<<node[o2].sz<<" "<<l<<" "<<r<<" "<<pos<<endl;
 51 }
 52 
 53 void update(int o , int l , int r , int pos , int v)
 54 {
 55    // cout<<pos<<" "<<l<<" "<<r<<" "<<v<<endl;
 56     if(l==r){
 57         node[o].sz += v;
 58         return;
 59     }
 60     define_m;
 61     if(m>=pos) {
 62         if(!LS(o)){
 63             LS(o) = tot++;
 64             node[LS(o)].init();
 65         }
 66         update(LS(o) , l , m , pos , v);
 67     }
 68     else {
 69         if(!RS(o)){
 70             RS(o) = tot++;
 71             node[RS(o)].init();
 72         }
 73         update(RS(o) , m+1 , r , pos , v);
 74     }
 75     node[o].sz = node[LS(o)].sz+node[RS(o)].sz;
 76 }
 77 
 78 void add(int x , int pos , int v)
 79 {
 80     while(x<=n){
 81         if(!T2[x]){
 82             node[tot].init();
 83             T2[x] = tot++;
 84         }
 85         update(T2[x] , 1 , n , pos , v);
 86         x += lowbit(x);
 87     }
 88 }
 89 
 90 int query(vector<int> v1 , vector<int> v2 , int o1 , int o2 , int l , int r , int k)
 91 {
 92    // cout<<"fuck: "<<l<<" "<<r<<" "<<k<<endl;
 93     if(l==r) return l;
 94     define_m;
 95     int c1 = node[LS(o2)].sz-node[LS(o1)].sz , l1=v1.size() , l2=v2.size();
 96    // cout<<"st: "<<l1<<" "<<l2<<" "<<o1<<" "<<o2<<" "<<node[LS(o2)].sz<<" "<<node[LS(o1)].sz<<" "<<l<<" "<<r<<" "<<k<<endl;
 97     for(int i=0 ; i<l1 ; i++){
 98 
 99         c1-=node[LS(v1[i])].sz;
100     }
101     for(int i=0 ; i<l2 ; i++){
102         // if(node[LS(v2[i])].sz) cout<<"i: "<<i<<" "<<node[LS(v2[i])].sz<<endl;
103         c1+=node[LS(v2[i])].sz;
104     }
105   //  cout<<"en: "<<l1<<" "<<l2<<" "<<o1<<" "<<o2<<" "<<c1<<" "<<l<<" "<<r<<" "<<k<<endl;
106     if(c1 >= k){
107         for(int i=0 ; i<l1 ; i++) v1[i] = LS(v1[i]);
108         for(int i=0 ; i<l2 ; i++) v2[i] = LS(v2[i]);
109         return query(v1 , v2 , LS(o1) , LS(o2) , l , m , k);
110     }else{
111         for(int i=0 ; i<l1 ; i++) v1[i] = RS(v1[i]);
112         for(int i=0 ; i<l2 ; i++) v2[i] = RS(v2[i]);
113         return query(v1 , v2 , RS(o1) , RS(o2) , m+1 , r , k-c1);
114     }
115 }
116 
117 int query(int s , int t , int k)
118 {
119     v1.clear() , v2.clear();
120     int x = s-1;
121     while(x>0){
122         v1.push_back(T2[x]);
123         x-=lowbit(x);
124     }
125     x = t;
126     while(x>0){
127         v2.push_back(T2[x]);
128         x-=lowbit(x);
129     }
130     return query(v1 , v2 , T1[s-1]  ,T1[t] , 1 , n , k);
131 }
132 
133 char str[7];
134 int cur[N];
135 
136 int main()
137 {
138     //freopen("in.txt" , "r" , stdin);
139     //freopen("out1.txt" , "w" , stdout);
140     int T;
141     scanf("%d" , &T);
142     while(T--){
143         scanf("%d%d" , &n , &m);
144         tot = 0;
145         for(int i=0 ; i<n ; i++){
146             scanf("%d" , val+i);
147             cur[i+1] = val[i];
148         }
149         int cnt = n;
150         for(int i=0 ; i<m ; i++){
151             scanf("%s%d%d" , str , &s[i] , &t[i]);
152             if(str[0] == 'Q'){
153                 scanf("%d" , &rank[i]);
154                 op[i] = 1;
155             }
156             else{
157                 op[i] = 0;
158                 val[cnt++] = t[i];
159             }
160         }
161         sort(val , val+cnt);
162         int pren = n;
163         n = unique(val , val+cnt)-val;
164        // cout<<pren<<" "<<n<<endl;
165         //初始建立静态主席树
166         T1[0] = build(1 , n);
167         for(int i=1 ; i<=pren ; i++){
168             node[tot].init();
169             T1[i] = tot++;
170             build(T1[i-1] , T1[i] , 1 , n , Hash(cur[i]) , 1 , i);
171         }
172 
173         memset(T2 , 0 , sizeof(T2));
174         for(int i=0 ; i<m ; i++){
175             if(op[i]){
176                 int pos = query(s[i] , t[i] , rank[i]);
177                 printf("%d
" , val[pos-1]);
178             }else{
179                 add(s[i] , Hash(cur[s[i]]) , -1);
180                 add(s[i] , Hash(t[i]) , 1);
181                 cur[s[i]] = t[i];
182             }
183         }
184     }
185     return 0;
186 }

  

原文地址:https://www.cnblogs.com/CSU3901130321/p/4775358.html