zoukankan      html  css  js  c++  java
  • 【BZOJ 3110】 [Zjoi2013]K大数查询(整体二分)

    【题目】

    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

     
     
    【分析】
      这个,区间修改,树套树感觉还是可以的,就是线段树套字母树?(大家写的都是套平衡树,我爱字母树),然后线段树上是区间修改,所以要打lazy标记。
      但是我不打树套树!!自从上次爆空间之后【TAT 可能大神要说套平衡树啊不会爆..【我平衡树垃圾。。。
      然后我试着用CDQ分治?【天哪怎么不行的说。。。。跟上一题怎么不一样TAT
      然后就去搜题解——整体二分。。。
      我觉得他跟CDQ分治还是很不一样的,CDQ分治是做[l,mid]对[mid+1,r]的答案,对什么三维偏序的独大,他是把时间维弄成一维,普通的单点修改题就可以看成n维偏序了。
      但是,这题是区间修改,【好像不行,反正我想了很久没想到ORZ..区间跨mid怎么破。。
      
      正题-。-
    用solve(l,r,S)表示现在处理S集合,S集合是操作集合按照时间排序,所有插入操作满足插入的球数值在l~r,所有询问操作满足其答案在区间l~r。 
    每个询问操作需要保存一个cnt代表目前在其询问的对应区间内>r的有多少个。 
    然后我们按顺序扫描操作。先记mid=(l+r)/2 
    对于插入操作,如果其插入的球数值>mid那么我们将对应区间加1(用线段树维护区间内mid+1~r的球个数)。然后根据其数值让其进入l~mid或mid+1~r。 
    对于询问操作,我们得到其区间内数值为mid+1~r的个数j,然后如果j+cnt<=k-1那么显然mid不可能是该询问的答案,将该询问进入l~mid并更新其的cnt否则进入mid+1~r。 
    然后做到l=r的时候就可以解决所有进入此区间的询问。 
     
     
      我觉得网上的题解都不怎么说人话的【我垃圾看了好久
      二分的是答案!!![l,mid][mid+1,r]是值来的,不是区间。
      如果你插入的数<mid,那就分在做区间,否则是右区间。
      然后,对于询问,他答案是多少,就分到那个区间【QQQ:鬼知道他答案多少a..知道答案是多少还用你算。。。
      【AAA:Hhh,但你可以知道他是否大于mid啊,你把插入的数>=mid的操作做一下,就是标记那个区间加了一个大于mid的数,(树状数组维护),然后看看你的询问区间里面标记了多少个数大于mid了,如果有很多,那么就是右区间,如果不足够你询问的排名,就是左区间
      【%&&%:哇好神奇!!!
      注意哦,如果询问被分到了左区间,要剪掉答案在右区间的影响哦【虽然你的答案不在右区间,但是他们占排名,所以询问的排名要减掉他。。
      【代码实现还是很神奇的啊【我还看了别人代码才打的。
      看discuss说会爆int,要用unsigned int 我WA了很久,一生气,全LL就A了、.
      其实题目说有负数,但是我知道数据没有,就偷懒没写啦Hhh
     
    垃圾代码:
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 #define INF 0xfffffff
     9 #define Maxn 50010
    10 #define LL long long
    11 
    12 struct work
    13 {
    14     LL l,r,c,p,ans;
    15 }t[Maxn];
    16 
    17 LL a[Maxn],a1[Maxn],a2[Maxn],ans[Maxn];
    18 LL n,m;
    19 
    20 LL c1[Maxn],c2[Maxn];
    21 void add(LL l,LL r,LL c)
    22 {
    23     // printf("add %d %d %d
    ",l,r,c);
    24     for(LL i=l;i<=n;i+=i&(-i))
    25         c1[i]+=c,c2[i]+=l*c;
    26     r++;
    27     for(LL i=r;i<=n;i+=i&(-i))
    28         c1[i]-=c,c2[i]-=r*c;
    29 }
    30 
    31 LL query(LL l,LL r)
    32 {
    33     // printf("ask %d %d ",l,r);
    34     LL ans=0;
    35     for(LL i=r;i>=1;i-=i&(-i))
    36         ans+=c1[i]*(r+1)-c2[i];
    37     l--;
    38     for(LL i=l;i>=1;i-=i&(-i))
    39         ans-=c1[i]*(l+1)-c2[i];
    40     // printf("%d
    ",ans);
    41     return ans;
    42 }
    43 
    44 void solve(LL x,LL y,LL l,LL r)
    45 {
    46     if(l==r)
    47     {
    48         for(LL i=x;i<=y;i++) if(t[a[i]].p==2) t[a[i]].ans=l;
    49         return;
    50     }
    51     LL mid=(l+r)>>1;
    52     a1[0]=0;a2[0]=0;
    53     for(LL i=x;i<=y;i++)
    54     {
    55         if(t[a[i]].p==1)
    56         {
    57             if(t[a[i]].c<=mid) a1[++a1[0]]=a[i];
    58             else a2[++a2[0]]=a[i],add(t[a[i]].l,t[a[i]].r,1);
    59         }
    60         else
    61         {
    62             LL now=query(t[a[i]].l,t[a[i]].r);
    63             if(now>=t[a[i]].c) a2[++a2[0]]=a[i];
    64             else a1[++a1[0]]=a[i],t[a[i]].c-=now;
    65         }
    66     }
    67     for(LL i=x;i<=y;i++) if(t[a[i]].p==1&&t[a[i]].c>mid) add(t[a[i]].l,t[a[i]].r,-1);
    68     LL ll=a1[0],rr=a2[0];
    69     for(LL i=1;i<=ll;i++) a[x+i-1]=a1[i];
    70     for(LL i=1;i<=rr;i++) a[x+ll+i-1]=a2[i];
    71     solve(x,x+ll-1,l,mid);
    72     solve(x+ll,x+ll+rr-1,mid+1,r);
    73 }
    74 
    75 void init()
    76 {
    77     scanf("%lld%lld",&n,&m);
    78     for(LL i=1;i<=m;i++)
    79     {
    80         scanf("%lld%lld%lld%lld",&t[i].p,&t[i].l,&t[i].r,&t[i].c);
    81     }
    82     memset(c1,0,sizeof(c1));
    83     memset(c2,0,sizeof(c2));
    84     for(LL i=1;i<=m;i++) a[i]=i;
    85     solve(1,m,1,n);
    86 }
    87 
    88 int main()
    89 {
    90     init();
    91     for(LL i=1;i<=m;i++) if(t[i].p==2) printf("%lld
    ",t[i].ans);
    92     return 0;
    93 }
    View Code

    2016-11-09 13:46:58

  • 相关阅读:
    MS SQL日期處理
    VS2005快捷键大全
    聯接遠程務器進行操作
    Zune XNA 开发(一,Hello Zune)
    Silverlight for Google Picasa
    Moonlight已经可以下载,目前是0.6版
    Silverlight 2 Beta 2发布
    在Silverlight 2 beta1中使用IronPython等动态语言
    如何在现有通过AttachDbFilename连接的Sql Express数据库上设置membership
    XNA Game Studio 3.0 CTP让Zune不仅仅是媒体播放器
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6046643.html
Copyright © 2011-2022 走看看