Bzoj3110 [Zjoi2013]K大数查询

 

Time Limit: 20 Sec  Memory Limit: 512 MB
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

Sample Output

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\n",Que(a,b,c,1,n,1));
85         }
86     }
87     return 0;
88 }

 

posted @ 2017-01-30 21:21  SilverNebula  阅读(223)  评论(0编辑  收藏  举报
AmazingCounters.com