zoukankan      html  css  js  c++  java
  • BZOJ 3110 [Zjoi2013]K大数查询 (CDQ分治+树状数组)

    题目描述

    有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

    输入输出格式

    输入格式:

    第一行N,M接下来M行,每行形如1 a b c或2 a b c

    输出格式:

    输出每个询问的结果

    输入输出样例

    输入样例#1: 复制
    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 的数也只有 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<=long long

    题解

    据说这是一道CDQ的板子题(然而为什么还有大佬说这是整体二分呢……蒟蒻实在搞不清楚有什么不同的……)

    这里要二分的有两个,一个是询问,一个是答案(题目已经保证了答案都在1-n的范围内)

    先二分一个答案,如果查询所得的排名小于询问(即求得的k比询问小),说明答案应该更大,放到右边递归处理,否则答案应该更小,放到左边递归(放到左边的话要记得减掉查询出来的k)

    查询的话是区间修改和区间询问,用树状数组就可以了

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #define ll long long
     5 using namespace std;
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 inline int read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;int res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 char sr[1<<21],z[20];int C=-1,Z;
    19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    20 inline void print(int x){
    21     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    22     while(z[++Z]=x%10+48,x/=10);
    23     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    24 }
    25 const int N=50005;
    26 ll c1[N],c2[N];
    27 int ans[N],pd[N],n,m;
    28 struct node{
    29     int type,l,r,val,id;
    30     node(){}
    31     node(int type,int l,int r,int val,int id):type(type),l(l),r(r),val(val),id(id){}
    32 }a[N],lef[N],rig[N];
    33 inline void add(int x,ll val){
    34     int t=x;
    35     for(int i=x;i<=n;i+=i&(-i))
    36     c1[i]+=val,c2[i]+=val*t;
    37 }
    38 inline ll sum(int x){
    39     ll res=0;
    40     for(int i=x;i;i-=i&(-i))
    41     res+=c1[i]*(x+1)-c2[i];
    42     return res;
    43 }
    44 void CDQ(int ql,int qr,int l,int r){
    45     if(ql>qr||l>r) return;
    46     if(l==r) {for(int i=ql;i<=qr;++i) ans[a[i].id]=l;return;}
    47     int mid=(l+r)>>1;
    48     int nowl=0,nowr=0;
    49     for(int i=ql;i<=qr;++i){
    50         if(a[i].type&1){
    51             if(a[i].val>mid) add(a[i].l,1),add(a[i].r+1,-1),rig[++nowr]=a[i];
    52             else lef[++nowl]=a[i];
    53         }
    54         else{
    55             ll now=sum(a[i].r)-sum(a[i].l-1);
    56             if(now>=a[i].val) rig[++nowr]=a[i];
    57             else a[i].val-=now,lef[++nowl]=a[i];
    58         }
    59     }
    60     for(int i=ql;i<=qr;++i)
    61     if((a[i].type&1)&&a[i].val>mid)
    62     add(a[i].l,-1),add(a[i].r+1,1);
    63     for(int i=1;i<=nowl;++i) a[ql+i-1]=lef[i];
    64     for(int i=1;i<=nowr;++i) a[ql+nowl-1+i]=rig[i];
    65     CDQ(ql,ql+nowl-1,l,mid);
    66     CDQ(ql+nowl,qr,mid+1,r);
    67 }
    68 int main(){
    69     //freopen("testdata.in","r",stdin);
    70     n=read(),m=read();
    71     for(int i=1;i<=m;++i){
    72         int type=read(),l=read(),r=read(),val=read();
    73         a[i]=node(type,l,r,val,i);
    74         if(type&2) pd[i]=1;
    75     }
    76     CDQ(1,m,1,n);
    77     for(int i=1;i<=m;++i)
    78     if(pd[i]) print(ans[i]);
    79     Ot();
    80     return 0;
    81 }
  • 相关阅读:
    Codeforces 1485C Floor and Mod (枚举)
    CodeForces 1195D Submarine in the Rybinsk Sea (算贡献)
    CodeForces 1195C Basketball Exercise (线性DP)
    2021年初寒假训练第24场 B. 庆功会(搜索)
    任务分配(dp)
    开发工具的异常现象
    Telink MESH SDK 如何使用PWM
    Telink BLE MESH PWM波的小结
    [LeetCode] 1586. Binary Search Tree Iterator II
    [LeetCode] 1288. Remove Covered Intervals
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9455917.html
Copyright © 2011-2022 走看看