• 动态 K th



      每一棵线段树是维护每一个序列前缀的值在任意区间的个数,如果还是按照静态的来做的话,那么每一次修改都要遍历O(n)棵树,时间就是O(2*M*nlogn)->TLE考虑到前缀和,我们通过树状数组来优化,即树状数组套主席树,每个节点都对应一棵主席树,那么修改操作就只要修改logn棵树,o(nlognlogn+Mlognlogn)时间是可以的,但是直接建树要nlogn*logn(10^7)会MLE我们发现对于静态的建树我们只要nlogn个节点就可以了,而且对于修改操作,只是修改M次,每次改变俩个值(减去原先的,加上现在的)也就是说如果把所有初值都插入到树状数组里是不值得的,所以我们分两部分来做,所有初值按照静态来建,内存O(nlogn),而修改部分保存在树状数组中,每次修改logn棵树,每次插入增加logn个节点O(M*logn*logn+nlogn)

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<vector>
      7 #include<cmath>
      8 #define ls(i) T[i].ls
      9 #define rs(i) T[i].rs
     10 #define w(i) T[i].w
     11 #define Find(i) (lower_bound(LX.begin(),LX.begin()+n1,i)-LX.begin())+1
     12 
     13 using namespace std;
     14 const int N=60000+10;
     15 struct node{
     16     int ls,rs,w;
     17     node(){ls=rs=w=0;}
     18 }T[2000000];
     19 struct ope{
     20     int i,l,r,k;
     21 }op[11000];
     22 vector<int> LX,Q1,Q2;
     23 int n,n1,m,cnt;
     24 int a[61000],root[61000*2];
     25 inline int lowbit(int x){
     26     return x&-x;
     27 }
     28 void build(int &i,int l,int r,int x){
     29     T[++cnt]=T[i]; i=cnt;
     30     w(i)++;
     31     if (l==r) return;
     32     int m=(l+r)>>1;
     33     if (x<=m) build(ls(i),l,m,x);
     34     else build(rs(i),m+1,r,x);
     35 }
     36 void ins(int &i,int l,int r,int x,int v){
     37     if (i==0){ T[++cnt]=T[i]; i=cnt; }
     38     w(i)+=v;
     39     if (l==r) return;
     40     int m=(l+r)>>1;
     41     if (x<=m) ins(ls(i),l,m,x,v);
     42     else ins(rs(i),m+1,r,x,v);
     43 }
     44 void my_ins(int pos,int x,int v){
     45     int t=Find(x);
     46     for (int i=pos;i<=n;i+=lowbit(i)){
     47         ins(root[i],1,n1,t,v);
     48     }
     49 }
     50 int Qy(vector<int> Q1,vector<int> Q2,int l,int r,int k){
     51     if (l==r) return l;
     52     int c=0;
     53     int m=(l+r)>>1;
     54     for (int i=0;i<Q1.size();i++) c-=w(ls(Q1[i]));
     55     for (int i=0;i<Q2.size();i++) c+=w(ls(Q2[i]));
     56     for (int i=0;i<Q1.size();i++) Q1[i]=(c>=k?ls(Q1[i]):rs(Q1[i]));
     57     for (int i=0;i<Q2.size();i++) Q2[i]=(c>=k?ls(Q2[i]):rs(Q2[i]));
     58 
     59     if (c>=k) return Qy(Q1,Q2,l,m,k);
     60     else return Qy(Q1,Q2,m+1,r,k-c);
     61 }
     62 void query(int l,int r,int k){
     63     Q1.clear();Q2.clear();
     64     Q1.push_back(root[l!=1?l-1+n:0]);
     65     Q2.push_back(root[r+n]);
     66     for (int i=l-1;i>0;i-=lowbit(i)) Q1.push_back(root[i]);
     67     for (int i=r;i>0;i-=lowbit(i)) Q2.push_back(root[i]);
     68 
     69     int t=Qy(Q1,Q2,1,n1,k);
     70     printf("%d
    ",LX[t-1]);
     71 }
     72 void work(){
     73     cnt=0;
     74     //for (int i=0;i<n1;i++) cout<<list[i]<<" ";cout<<endl;
     75     memset(root,0,sizeof(root));
     76     for (int i=1;i<=n;i++){
     77         root[i+n]=root[i-1+n];
     78         int t=Find(a[i]);
     79         build(root[i+n],1,n1,t);
     80     }
     81     for (int i=0;i<m;i++){
     82         if (op[i].i==0){
     83             query(op[i].l,op[i].r,op[i].k);
     84         //    cout<<"*** "<<i<<endl;
     85         }else{
     86             my_ins(op[i].l,a[op[i].l],-1);
     87             my_ins(op[i].l,op[i].r,1);
     88             a[op[i].l]=op[i].r;
     89         }
     90     }
     91 
     92 }
     93 int main(){
     94     int Cas;scanf("%d",&Cas);
     95     while (Cas--){
     96         scanf("%d%d",&n,&m);
     97         LX.clear();
     98         for (int i=1;i<=n;i++){
     99             scanf("%d",&a[i]);LX.push_back(a[i]);
    100         }
    101         char s[10];
    102         for (int i=0;i<m;i++){
    103             scanf("%s",s);
    104             if (s[0]=='Q'){
    105                 op[i].i=0;
    106                 scanf("%d%d%d",&op[i].l,&op[i].r,&op[i].k);
    107             }else{
    108                 op[i].i=1;
    109                 scanf("%d%d",&op[i].l,&op[i].r);
    110                 LX.push_back(op[i].r);
    111             }
    112         }
    113         sort(LX.begin(),LX.end());
    114         n1=unique(LX.begin(),LX.end())-LX.begin();
    115         work();
    116     }
    117 
    118 
    119     return 0;
    120 }

     转自:http://www.cnblogs.com/Rlemon/archive/2013/05/24/3096264.html

  • 相关阅读:
    HDU 2054 A == B ?(找小数点)
    javaWeb_使用标签库简化jsp
    EC2的维护更新-总结篇及有效经验分享
    SSLStrip 终极版 —— location 瞒天过海
    华为部分真机调试无法显示log问题解决
    LeetCode
    Tcl脚本调用高层API实现仪表使用和主机创建配置的自己主动化測试用例
    web工程调用hadoop集群1.2
    3DShader之移位贴图(Displacement Mapping)
    Java 学习第一天
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5236054.html
Copyright © 2020-2023  润新知