终于用主席树过了啊!!!!!
原来是要分两部分搞内存才耗得小啊!!!!!
尼玛ZOJ还不给自动刷新啊,每次交了都要手动search啊有木有!!!!!
分两部分是指原始数列建一个单纯的主席树,有更新的数列建一个用BIT维护的主席树,每次查询的时候在两部分同步二分查询。
主席树唯一的缺点就是耗内存太可怕了,减少消耗的方法以下两点:1、lazy标记,等到真正需要的时候才把这个节点建立起来,个人觉得用指向左右儿子的节点直接来判就好了,不用另外开一个域。2、尽可能多地复用节点,越早建树越好。
刚略有感悟,众犇轻喷即可……
#include <algorithm> #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <deque> #include <vector> #include <string> #include <bitset> #include <memory> #include <complex> #include <numeric> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h> #include <ctype.h> #include <locale.h> using namespace std; #pragma pack(4) const double eps = 1e-8; const double pi = acos(-1.0); const int inf = 0x7f7f7f7f; #define loop(a,n) \ for(int i=0;n>i;i++) \ cout<<a[i]<<(i!=n-1?' ':'\n') #define loop2(a,n,m) \ for(int i=0;n>i;i++) \ for(int j=0;m>j;j++) \ cout<<a[i][j]<<(j!=m-1?' ':'\n') #define at(a,i) ((a)&(1<<(i))) #define nt(a,i) ((a)^(1<<(i))) #define set1(a,i) ((a)|(1<<(i))) #define set0(a,i) ((a)&(~(1<<(i)))) #define gret(a,b) (((a)-(b))>eps) #define less(a,b) (((b)-(a))>eps) #define greq(a,b) (((a)-(b))>-eps) #define leeq(a,b) (((b)-(a))>-eps) #define equl(a,b) (fabs((a)-(b))<eps) #define lmax(a,b) ((a)>(b)?(a):(b)) #define lmin(a,b) ((a)<(b)?(a):(b)) #define fmax(a,b) (gret(a,b)?(a):(b)) #define fmin(a,b) (less(a,b)?(a):(b)) const int MAXV = 50002; const int MAXE = 10002; class CMT { private: struct node { int s; node *c[2]; int ls(void) { return this?c[0]->size():0; } int rs(void) { return this?c[1]->size():0; } int size(void) { return this?s:0; } }pool[MAXV*40],*a[MAXV],*b[MAXV],*c[33],*d[33]; int use,left,right,amount; node *malloc(node *root,int w) { node *now=&pool[use++]; if(!root) { now->s=w; now->c[0]=NULL; now->c[1]=NULL; } else { now->s=w+root->s; now->c[0]=root->c[0]; now->c[1]=root->c[1]; } return now; } int query(int k,int lc,int ld,int l,int r) { if(l==r) return l; else { int sum=0; for(int i=0;lc>i;i++) if(c[i]) sum-=c[i]->ls(); for(int i=0;ld>i;i++) if(d[i]) sum+=d[i]->ls(); if(sum>=k) { for(int i=0;lc>i;i++) if(c[i]) c[i]=c[i]->c[0]; for(int i=0;ld>i;i++) if(d[i]) d[i]=d[i]->c[0]; return query(k,lc,ld,l,(l+r)/2); } else { for(int i=0;lc>i;i++) if(c[i]) c[i]=c[i]->c[1]; for(int i=0;ld>i;i++) if(d[i]) d[i]=d[i]->c[1]; return query(k-sum,lc,ld,(l+r)/2+1,r); } } } node *insert(node *root,int x,int w,int l,int r) { root=malloc(root,w); if(l!=r) { if(x<=(l+r)/2) root->c[0]=insert(root->c[0],x,w,l,(l+r)/2); if((l+r)/2<x) root->c[1]=insert(root->c[1],x,w,(l+r)/2+1,r); } return root; } node *change(node *root,int x,int w,int l,int r) { if(!root) root=malloc(NULL,0); if(l!=r) { if(x<=(l+r)/2) root->c[0]=change(root->c[0],x,w,l,(l+r)/2); if((l+r)/2<x) root->c[1]=change(root->c[1],x,w,(l+r)/2+1,r); } return root->s+=w,root; } public: void clear(int n,int l,int r) { use=0; left=l; right=r; amount=n; for(int i=0;n>=i;i++) a[i]=b[i]=NULL; } int query(int x,int y,int k) { int lc=0,ld=0; c[lc++]=a[x]; d[ld++]=a[y]; for(int i=x;i>0;i-=(i&-i)) c[lc++]=b[i]; for(int i=y;i>0;i-=(i&-i)) d[ld++]=b[i]; return query(k,lc,ld,left,right); } void insert(int i,int x,int w) { a[i]=insert(a[i-1],x,w,left,right); } void change(int i,int x,int w) { while(i<=amount) { b[i]=change(b[i],x,w,left,right); i+=(i&-i); } } }cmt; struct CMD { char o; int x,y,k; }cmd[MAXE]; int tcase,n,m,w,a[MAXV],b[MAXV+MAXE]; int rank(int val,int tot) { return lower_bound(b,b+tot,val)-b; } int main() { #ifndef ONLINE_JUDGE freopen("Dynamic Rankings.txt","r",stdin); #endif scanf("%d",&tcase);while(tcase--) { scanf("%d %d",&n,&m); int cnt=0; for(int i=0;n>i;i++) { scanf("%d",&a[i]); b[cnt++]=a[i]; } for(int i=0;m>i;i++) { getchar(); scanf("%c",&cmd[i].o); if(cmd[i].o=='Q') { scanf("%d %d %d",&cmd[i].x,&cmd[i].y,&cmd[i].k); } else if(cmd[i].o=='C') { scanf("%d %d",&cmd[i].x,&cmd[i].y); b[cnt++]=cmd[i].y; } } int tot=1; sort(b,b+cnt); for(int i=1;cnt>i;i++) { if(b[i]!=b[i-1]) b[tot++]=b[i]; } cmt.clear(n,0,tot-1); for(int i=0;n>i;i++) { cmt.insert(i+1,rank(a[i],tot),+1); } for(int i=0;m>i;i++) { if(cmd[i].o=='Q') { printf("%d\n",b[cmt.query(cmd[i].x-1,cmd[i].y,cmd[i].k)]); } else if(cmd[i].o=='C') { cmt.change(cmd[i].x,rank(a[cmd[i].x-1],tot),-1); a[cmd[i].x-1]=cmd[i].y; cmt.change(cmd[i].x,rank(a[cmd[i].x-1],tot),+1); } } } return 0; }