3110: [Zjoi2013]K大数查询
Time Limit: 20 Sec Memory Limit: 512 MB Submit: 9208 Solved: 2737 [Submit][Status][Discuss]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
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #define M 15000000 8 using namespace std; 9 long long read() 10 { 11 long long x=0,f=1;char ch=getchar(); 12 while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();} 13 while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 long long cnt=0; 17 long long n,m; 18 long long a,b,c; 19 long long root[200005],sum[M],ls[M],rs[M],lazy[M]; 20 void add(long long &now,long long l,long long r,long long L,long long R) 21 { 22 if(!now) now=++cnt; 23 long long mid=(l+r)>>1; 24 if(l>=L&&r<=R){sum[now]+=r-l+1,lazy[now]++; return;} 25 if(L<=mid)add(ls[now],l,mid,L,R); 26 if(R>mid)add(rs[now],mid+1,r,L,R); 27 sum[now]+=min(R,r)-max(L,l)+1; 28 } 29 long long ask(long long now,long long l,long long r,long long L,long long R) 30 { 31 if(!now) return 0; 32 long long mid=(l+r)>>1; 33 if(l>=L&&r<=R) return sum[now]; 34 long long ans=0; 35 if(L<=mid) ans+=ask(ls[now],l,mid,L,R); 36 if(R>mid)ans+=ask(rs[now],mid+1,r,L,R); 37 return ans+(min(R,r)-max(L,l)+1)*lazy[now]; 38 } 39 void insert() 40 { 41 long long l=1,r=n,now=1; 42 while(l<r) 43 { 44 long long mid=(l+r)>>1; 45 add(root[now],1,n,a,b); 46 if(c<=mid) r=mid,now<<=1; 47 else l=mid+1,now=(now<<1)+1; 48 } 49 add(root[now],1,n,a,b); 50 } 51 long long query() 52 { 53 long long l=1,r=n,now=1; 54 while(l<r) 55 { 56 long long mid=(l+r)>>1; 57 now<<=1; 58 long long k=ask(root[now+1],1,n,a,b); 59 if(k>=c) l=mid+1,now++; 60 else r=mid,c-=k; 61 } 62 return l; 63 } 64 int main() 65 { 66 n=read(),m=read(); 67 while(m--) 68 { 69 long long flag=read();a=read(),b=read(),c=read(); 70 if(flag==1) insert(); 71 else printf("%lld ",query()); 72 } 73 }