zoukankan      html  css  js  c++  java
  • 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-ans[i]+1);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    [PHP] Layui + jquery 实现 实用的文章自定义标签
    个人总结第五周
    个人总结第四周
    个人总结第三周
    个人总结第二周
    个人总结第一周
    用户体验评价
    第二阶段scrum冲刺
    单词统计
    用户模块和用户场景
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9463146.html
Copyright © 2011-2022 走看看