zoukankan      html  css  js  c++  java
  • 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 }

      

  • 相关阅读:
    无锁数据结构(Lock-Free Data Structures)
    Grouping Sets:CUBE和ROLLUP从句
    SQL Server里Grouping Sets的威力
    第18/24周 乐观并发控制(Optimistic Concurrency)
    SQL Server里PIVOT运算符的”红颜祸水“
    数据库收缩:NOTRUNCATE与TRUNCATEONLY
    在SQL Server里为什么我们需要更新锁
    SQL Server里的自旋锁介绍
    SQL Server里的闩锁介绍
    配置内存中OLTP文件组提高性能
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4775358.html
Copyright © 2011-2022 走看看