BZOJ3110: [Zjoi2013]K大数查询
n<=50000个vector进行m<=50000次操作:1、一区间的vector插入一个数;2、查询一区间中的vector中的所有数的第k大。
方法一:普通线段树套权值线段树!……
方法二:单个询问是可以二分的,那就整体二分吧。这次是用线段树维护,把所有数字反过来求第k小再反过来就是第k大,注意50000*50000>int。
1 #include<string.h> 2 #include<stdlib.h> 3 #include<stdio.h> 4 //#include<assert.h> 5 #include<algorithm> 6 //#include<iostream> 7 using namespace std; 8 9 int n,m; 10 #define maxn 100011 11 #define LL long long 12 struct Ope 13 { 14 int x,y; LL z; int id,type; 15 //type=1:xiugai,[x,y] ba zhi z jia 1 16 //type=0:chaxun,[x,y] cha di z da,xunwen bian hao id 17 }q[maxn],al[maxn],ar[maxn];int len=0; 18 int ans[maxn]; 19 20 struct SMT 21 { 22 struct Node 23 { 24 int ls,rs; 25 int add; LL sum; 26 }a[maxn<<1]; 27 int size,root; 28 void clear() {size=root=0;} 29 void up(int x) 30 { 31 const int &p=a[x].ls,&q=a[x].rs; 32 a[x].sum=a[p].sum+a[q].sum; 33 } 34 void addsingle(int x,int L,int R,int v) 35 { 36 a[x].sum+=(R-L+1)*1ll*v; 37 a[x].add+=v; 38 } 39 void down(int x,int L,int R) 40 { 41 int mid=(L+R)>>1,&p=a[x].ls,&q=a[x].rs; 42 if (!p) {p=++size; a[p].ls=a[p].rs=a[p].sum=a[p].add=0;} 43 if (!q) {q=++size; a[q].ls=a[q].rs=a[q].sum=a[q].add=0;} 44 if (a[x].add) addsingle(p,L,mid,a[x].add),addsingle(q,mid+1,R,a[x].add),a[x].add=0; 45 } 46 int ql,qr,v; 47 void Add(int &x,int L,int R) 48 { 49 if (!x) {x=++size; a[x].add=a[x].sum=a[x].ls=a[x].rs=0;} 50 if (ql<=L && R<=qr) {addsingle(x,L,R,v); return;} 51 down(x,L,R); 52 const int mid=(L+R)>>1; 53 if (ql<=mid) Add(a[x].ls,L,mid+0); 54 if (qr> mid) Add(a[x].rs,mid+1,R); 55 up(x); 56 } 57 void add(int L,int R,int v) 58 { 59 ql=L; qr=R; this->v=v; 60 Add(root,1,n); 61 } 62 LL Query(int &x,int L,int R) 63 { 64 if (!x) {x=++size; a[x].add=a[x].sum=a[x].ls=a[x].rs=0;} 65 if (ql<=L && R<=qr) return a[x].sum; 66 down(x,L,R); 67 const int mid=(L+R)>>1; LL ans=0; 68 if (ql<=mid) ans+=Query(a[x].ls,L,mid+0); 69 if (qr> mid) ans+=Query(a[x].rs,mid+1,R); 70 return ans; 71 } 72 LL query(int L,int R) 73 { 74 ql=L; qr=R; 75 return Query(root,1,n); 76 } 77 }t; 78 79 void solve(int L,int R,int ql,int qr) 80 { 81 if (L>R || ql>qr) return; 82 if (L==R) 83 { 84 for (int i=ql;i<=qr;i++) if (q[i].type==0) ans[q[i].id]=L; 85 return; 86 } 87 t.clear(); 88 int mid=(L+R)>>1,lal=0,lar=0; 89 for (int i=ql;i<=qr;i++) 90 { 91 if (q[i].type==1) 92 { 93 if (q[i].z<=mid) t.add(q[i].x,q[i].y,1),al[++lal]=q[i]; 94 else ar[++lar]=q[i]; 95 } 96 else 97 { 98 LL tmp=t.query(q[i].x,q[i].y); 99 if (tmp>=q[i].z) al[++lal]=q[i]; 100 else q[i].z-=tmp,ar[++lar]=q[i]; 101 } 102 } 103 for (int i=1,j=ql;i<=lal;i++,j++) q[j]=al[i]; 104 for (int i=1,j=ql+lal;i<=lar;i++,j++) q[j]=ar[i]; 105 solve(L,mid,ql,ql+lal-1); 106 solve(mid+1,R,ql+lal,qr); 107 } 108 109 int main() 110 { 111 scanf("%d%d",&n,&m); 112 int cntq=0; 113 for (int i=1,op;i<=m;i++) 114 { 115 scanf("%d",&op); 116 if (op==1) len++,scanf("%d%d%lld",&q[len].x,&q[len].y,&q[len].z),q[len].z*=-1,q[len].type=1; 117 else len++,scanf("%d%d%lld",&q[len].x,&q[len].y,&q[len].z),q[len].id=++cntq,q[len].type=0; 118 } 119 solve(-n,n,1,len); 120 for (int i=1;i<=cntq;i++) printf("%d\n",-ans[i]); 121 return 0; 122 }