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

  • 相关阅读:
    UVA1349 Optimal Bus Route Design 最优巴士路线设计
    POJ3565 Ants 蚂蚁(NEERC 2008)
    UVA1663 Purifying Machine 净化器
    UVa11996 Jewel Magic 魔法珠宝
    NEERC2003 Jurassic Remains 侏罗纪
    UVA11895 Honorary Tickets
    gdb调试coredump(使用篇)
    使用 MegaCLI 检测磁盘状态并更换磁盘
    员工直接坦诚直来直去 真性情
    山东浪潮超越3B4000申泰RM5120-L
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5236054.html
Copyright © 2011-2022 走看看