zoukankan      html  css  js  c++  java
  • P3332 [ZJOI2013]K大数查询

    题目描述

    有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<=Maxlongint

               算法一:区间线段树+权值线段树  

               算法二:整体二分+区间修改/询问树状数组

                   整体二分部分正如上文,但是本题重点在于区间修改/询问树状数组

                   1.单点修改+单点询问

                      普通树状数组即可

                   2.区间修改+单点询问

                      考虑差分即可

                      我们兴建一个查分数组来做树状数组,并且将原有a数组保留  

                      修改时就修改delta数组即可

                      询问就加上delta的前缀和与a数组即可

                   3.区间修改+区间询问

                      首先依旧是引入delta数组 delta[i]表示区间 [i, n] 的共同增量

                      于是修改区间 [l, r] 时修改 delta[l] 和 delta[r + 1] 即可(就是差分的思路)

                      查询的时候是查询区间 [l, r] 的和 即sum[r] - sum[l - 1] 所以现在的问题是求sum[i]

                      sum[i]=a[1]+....+a[i]+delta[1]*i+delta[2]*(i-1)...delta[i]*1

                          =sigma(a[x])+sigma(delta[x]*(i+1-x))

                          =sigma(a[x])+(i+1)*sigma(delta[x])-sigma(delta[x]*x)

                      于是维护两个树状数组delta[x]和delta[x]*x即可!

    //luogu rank1 1049ms
    //@2017-03-06 14:13
    #include<cstdio>
    #include<iostream>
    #define ll long long 
    #define EP if(ch==EOF) return EOF;
    using namespace std;
    inline int read(){
        int x=0,f=1;char ch=getchar();EP
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();EP}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int Z=6e4+5;
    struct node{
        int x,y,k,opt,id;
    }p[Z],p1[Z],p2[Z];
    int n,m,cnt,ans[Z];
    ll bit[Z],BIT[Z];
    int mx,mn;
    inline int lowbit(int x){
        return x&-x;
    }
    inline void update(int x,int d){
        ll k=(ll)x*d;
        for(int i=x;i<=n;i+=lowbit(i)) bit[i]+=d,BIT[i]+=k;
    }
    inline ll ask(int x){
        ll res=0;
        for(int i=x;i;i-=lowbit(i)) res+=bit[i];
        res*=x+1;
        for(int i=x;i;i-=lowbit(i)) res-=BIT[i];
        return res;
    }
    void solve(int l,int r,int x,int y){
        if(l>r||x>y) return ;
        if(x==y){
            for(int i=l;i<=r;i++) if(!p[i].opt) ans[p[i].id]=x;
            return ;
        }
        int mid=x+y>>1,t1(0),t2(0);
        ll tt(0);
        for(int i=l;i<=r;i++){
            if(p[i].opt){
                if(p[i].k<=mid){
                    p1[++t1]=p[i];
                    update(p[i].x,1);
                    update(p[i].y+1,-1);
                }
                else{
                    p2[++t2]=p[i];
                }
            }
            else{
                tt=ask(p[i].y)-ask(p[i].x-1);
                if(p[i].k<=tt){
                    p1[++t1]=p[i];
                }
                else{
                    p[i].k-=tt;
                    p2[++t2]=p[i];
                }
            }
        }
        for(int i=1;i<=t1;i++) if(p1[i].opt) update(p1[i].x,-1),update(p1[i].y+1,1);
        for(int i=1;i<=t1;i++) p[l+i-1]=p1[i];
        for(int i=1;i<=t2;i++) p[l+t1+i-1]=p2[i];
        solve(l,l+t1-1,x,mid);
        solve(l+t1,r,mid+1,y);
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++){
            p[i].opt=read()&1;
            p[i].x=read();
            p[i].y=read();
            p[i].k=read();
            if(p[i].opt) p[i].k=n-p[i].k;
            else p[i].id=++cnt;
        }
        solve(1,m,0,n<<1);
        for(int i=1;i<=cnt;i++) printf("%d
    ",n-ans[i]);
        return 0;
    }
  • 相关阅读:
    English trip V1
    English trip V1
    第一类斯特林数
    bzoj 3601 一个人的数论
    bzoj 4407 于神之怒加强版
    bzoj 2693 jzptab
    bzoj 4184 shallot
    luogu P3920 [WC2014]紫荆花之恋
    bzoj 4269 再见Xor
    luogu P2183 [国家集训队]礼物
  • 原文地址:https://www.cnblogs.com/shenben/p/6513079.html
Copyright © 2011-2022 走看看