bzoj3110 K大数查询

来源:互联网 发布:2016年淘宝用户人数 编辑:程序博客网 时间:2024/05/17 06:35
题目:有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c

如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。

N<=50000

M<=50000

思路:二分答案,要用到树状数组区间更新

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<ctime>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3f//0x3f3f3f3fconst int maxn=5e4+50;struct Node{    int type,id,a,b;    LL c;}q[maxn],q1[maxn],q2[maxn];struct BIT{    int n;    LL bit0[maxn],bit1[maxn];    void init(int _n){        n=_n;        mm(bit0,0);        mm(bit1,0);    }    void add(LL *b,int i,LL val){        for(;i<=n;i+=i&(-i))            b[i]+=val;    }    LL sum(LL *b,int i){        LL ret=0;        for(;i>0;i-=i&(-i))            ret+=b[i];        return ret;    }    void ADD(int l,int r,LL c){        add(bit0,l,-c*(l-1));        add(bit0,r+1,c*r);        add(bit1,l,c);        add(bit1,r+1,-c);    }    LL SUM(int l,int r){        LL ret=sum(bit0,r)-sum(bit0,l-1);        ret+=sum(bit1,r)*r-sum(bit1,l-1)*(l-1);        return ret;    }}bit;int ans[maxn],vis[maxn];int n,m;void cdq(int L,int R,int l,int r){    if(L>R) return;    if(l==r){        for(int i=L;i<=R;i++)            if(q[i].type==2)                ans[q[i].id]=l;        return;    }    int sz1=0,sz2=0,mid=(l+r)>>1;    for(int i=L;i<=R;i++){        if(q[i].type==1){            if(q[i].c<=mid) q1[sz1++]=q[i];            else{                bit.ADD(q[i].a,q[i].b,1);                q2[sz2++]=q[i];            }        }        else{            LL ret=bit.SUM(q[i].a,q[i].b);            if(ret>=q[i].c){                q2[sz2++]=q[i];            }            else{                q[i].c-=ret;                q1[sz1++]=q[i];            }        }    }    for(int i=0;i<sz2;i++)        if(q2[i].type==1)            bit.ADD(q2[i].a,q2[i].b,-1);    memcpy(q+L,q1,sz1*sizeof(Node));    memcpy(q+L+sz1,q2,sz2*sizeof(Node));    cdq(L,L+sz1-1,l,mid);    cdq(L+sz1,R,mid+1,r);}int main(){//    freopen("D:\\input.txt","r",stdin);//    freopen("D:\\output.txt","w",stdout);    while(~scanf("%d%d",&n,&m)){        bit.init(n);        mm(vis,0);        mm(ans,0);        int mi=n,mx=-n;        for(int i=1;i<=m;i++){            scanf("%d%d%d%lld",&q[i].type,&q[i].a,&q[i].b,&q[i].c);            q[i].id=i;            if(q[i].type==2)                vis[i]=1;            else{                mi=min(mi,(int)q[i].c);                mx=max(mx,(int)q[i].c);            }        }        cdq(1,m,mi,mx);        for(int i=1;i<=m;i++)            if(vis[i])                printf("%d\n",ans[i]);    }    return 0;}



原创粉丝点击