题目大意:
动态单点更新,然后多次询问求区间内第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\n" , 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 }
我还在坚持,我还未达到我所想,梦~~一直在