Submit: 6644 Solved: 2160
Description
有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
Input
第一行N,M
接下来M行,每行形如1 a b c或2 a b c
Output
输出每个询问的结果
Sample Input
2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
Sample Output
1
2
1
2
1
HINT
【样例说明】
第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1
的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是
1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3
大的数是 1 。
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
2操作中c<=Maxlongint
Source
树套树
外:权值线段树 内:区间线段树
数据会爆int,坑
跑得巨慢
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int mxn=21000100; 8 int read(){ 9 int x=0,f=1;char ch=getchar(); 10 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 11 while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();} 12 return x*f; 13 } 14 struct node{ 15 int l,r; 16 unsigned int sum,mk; 17 }t[mxn]; 18 int rot[mxn]; 19 int n,m,cnt=0; 20 void update(int v,int l,int r,int rt){ 21 t[rt].sum+=v*(r-l+1); 22 t[rt].mk+=v; 23 return; 24 } 25 void pushdown(int l,int r,int rt){ 26 if(l==r)return; 27 if(!t[rt].l) t[rt].l=++cnt; 28 if(!t[rt].r) t[rt].r=++cnt; 29 int mid=(l+r)>>1; 30 update(t[rt].mk,l,mid,t[rt].l); 31 update(t[rt].mk,mid+1,r,t[rt].r); 32 t[rt].mk=0; 33 return; 34 } 35 void Update(int L,int R,int l,int r,int &rt){ 36 if(!rt)rt=++cnt; 37 if(L<=l && r<=R){ 38 update(1,l,r,rt);return; 39 } 40 if(t[rt].mk)pushdown(l,r,rt); 41 int mid=(l+r)>>1; 42 if(L<=mid)Update(L,R,l,mid,t[rt].l); 43 if(R>mid)Update(L,R,mid+1,r,t[rt].r); 44 t[rt].sum=t[t[rt].l].sum+t[t[rt].r].sum; 45 return; 46 } 47 void insert(int a,int b,int c,int l,int r,int rt){ 48 while(l!=r){ 49 Update(a,b,1,n,rot[rt]); 50 int mid=(l+r)>>1; 51 if(c<=mid)r=mid,rt=rt<<1; 52 else l=mid+1,rt=rt<<1|1; 53 } 54 Update(a,b,1,n,rot[rt]); 55 return; 56 } 57 unsigned int query(int L,int R,int l,int r,int rt){ 58 if(!rt)return 0; 59 if(L<=l && r<=R){return t[rt].sum;} 60 if(t[rt].mk)pushdown(l,r,rt); 61 int mid=(l+r)>>1,res=0; 62 if(L<=mid)res+=query(L,R,l,mid,t[rt].l); 63 if(R>mid)res+=query(L,R,mid+1,r,t[rt].r); 64 return res; 65 } 66 unsigned int Que(int a,int b,unsigned int c,int l,int r,int rt){ 67 while(l!=r){ 68 unsigned int res=query(a,b,1,n,rot[rt<<1|1]); 69 int mid=(l+r)>>1; 70 if(res>=c)l=mid+1,rt=rt<<1|1; 71 else c-=res,r=mid,rt=rt<<1; 72 } 73 return l; 74 } 75 int main(){ 76 int i,j,a,b,c,op; 77 n=read();m=read(); 78 while(m--){ 79 op=read();a=read();b=read();c=read(); 80 if(op==1){ 81 insert(a,b,c,1,n,1); 82 } 83 else{ 84 printf("%u ",Que(a,b,c,1,n,1)); 85 } 86 } 87 return 0; 88 }