BZOJ 3110 [Zjoi2013]K大数查询(整体二分)

3110: [Zjoi2013]K大数查询

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 11654  Solved: 3505
[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

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

题解

求第K大。

然后我们把权值设为n-c+1;

最后答案为n-ans+1就把问题转化为了第k小

不过这题是插入。其实不是很难毕竟只是把权值小于mid的数的位置都加一就行了,我们把修改二分和一个位置多少个权值没有关系。

和以前唯一的区别就是这次是整体修改,用线段树就行了(就是慢)

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<algorithm>
  6 using namespace std;
  7 const long long N=100010;
  8 struct query{
  9     long long type,x,y,w,id;
 10 }q[N],c2[N],c1[N];
 11 long long ans[N],m,n,tot;
 12 struct tree{
 13     long long l,r,lazy,sum;
 14 }tr[N*5]; 
 15 void update(long long now){
 16     tr[now].sum=tr[now*2].sum+tr[now*2+1].sum;
 17 }
 18 void pushdown(long long now){
 19     if(tr[now].lazy==0)return;
 20     tr[now*2].sum+=(tr[now*2].r-tr[now*2].l+1)*tr[now].lazy;
 21     tr[now*2+1].sum+=(tr[now*2+1].r-tr[now*2+1].l+1)*tr[now].lazy;
 22     tr[now*2].lazy+=tr[now].lazy;
 23     tr[now*2+1].lazy+=tr[now].lazy;
 24     tr[now].lazy=0; 
 25 }
 26 void build(long long l,long long r,long long now){
 27     tr[now].l=l;tr[now].r=r;
 28     if(l==r)return;
 29     long long mid=(l+r)>>1;
 30     build(l,mid,now*2);
 31     build(mid+1,r,now*2+1); 
 32 }
 33 void add(long long l,long long r,long long c,long long now){
 34     pushdown(now);
 35     if(tr[now].l==l&&tr[now].r==r){
 36         tr[now].sum+=(tr[now].r-tr[now].l+1)*c;
 37         tr[now].lazy+=c;
 38         return;
 39     }
 40     long long mid=(tr[now].l+tr[now].r)>>1;
 41     if(l>mid)add(l,r,c,now*2+1);
 42     else if(r<=mid)add(l,r,c,now*2);
 43     else{
 44         add(l,mid,c,now*2);
 45         add(mid+1,r,c,now*2+1);
 46     }
 47     update(now);
 48 }
 49 long long check(long long l,long long r,long long now){
 50     pushdown(now);
 51     if(tr[now].l==l&&tr[now].r==r){
 52         return tr[now].sum;
 53     }
 54     long long mid=(tr[now].l+tr[now].r)>>1;
 55     if(l>mid)return check(l,r,now*2+1);
 56     else if(r<=mid)return check(l,r,now*2);
 57     else return check(l,mid,now*2)+check(mid+1,r,now*2+1);
 58 }
 59 void solve(long long l,long long r,long long L,long long R){
 60     if(l>r)return ;
 61     if(L==R){
 62         for(long long i=l;i<=r;i++){
 63             if(q[i].type==2)ans[q[i].id]=L;
 64         }
 65         return;
 66     }
 67     long long mid=(L+R)>>1;
 68     long long lnow=0;long long rnow=0;
 69     for(long long i=l;i<=r;i++){
 70         if(q[i].type==1){
 71             if(q[i].w<=mid){
 72                 add(q[i].x,q[i].y,1,1);
 73                 c1[++lnow]=q[i];
 74             }
 75             else c2[++rnow]=q[i]; 
 76         }
 77         else{
 78             long long tmp=check(q[i].x,q[i].y,1);
 79             if(tmp>=q[i].w)c1[++lnow]=q[i];
 80             else{
 81                 q[i].w-=tmp;
 82                 c2[++rnow]=q[i];    
 83             }
 84         }
 85     }
 86     for(long long i=1;i<=lnow;i++){
 87         if(c1[i].type==1)add(c1[i].x,c1[i].y,-1,1);
 88     }
 89     for(long long i=1;i<=lnow;i++){
 90         q[l+i-1]=c1[i];
 91     }
 92     for(long long i=1;i<=rnow;i++){
 93         q[l+lnow+i-1]=c2[i];
 94     }
 95     solve(l,l+lnow-1,L,mid);
 96     solve(l+lnow,r,mid+1,R);
 97 }
 98 int main(){
 99     scanf("%lld%lld",&n,&m);
100     build(1,n,1);
101     for(long long i=1;i<=m;i++){
102         long long k,a,b,c;
103         scanf("%lld%lld%lld%lld",&k,&a,&b,&c);
104         if(k==1){
105             q[i].type=1;q[i].x=a;q[i].y=b;q[i].w=n-c+1;
106         }
107         else{
108             q[i].type=2;q[i].x=a;q[i].y=b;q[i].w=c;q[i].id=++tot;
109         }
110     }
111     solve(1,m,-n,n);
112     for(long long i=1;i<=tot;i++){
113         printf("%lld\n",n-ans[i]+1);
114     }
115     return 0;
116 }

 

posted @ 2018-08-12 15:23  Xu-daxia  阅读(227)  评论(0编辑  收藏  举报