zoukankan      html  css  js  c++  java
  • K大数查询(bzoj 3110)

    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大,整体二分的经典题目。
      思想和静态的是差不多的,即二分出答案之后用树状数组判断,但是这个题目树状数组用了两个,就不是很懂了。 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define lon long long
    #define N 50010
    using namespace std;
    lon n,m,c1[N],c2[N],ans[N],has[N];
    struct node{
        lon l,r,c,tp,id;
    };node a[N],q[N];
    void add(lon *c,lon i,lon b){
        for(;i<=n;i+=i&(-i))
            c[i]+=b;
    }
    lon sum(lon *c,lon i){
        lon r=0;
        for(;i;i-=i&(-i))
            r+=c[i];
        return r;
    }
    void modify(lon l,lon r,lon c){
        add(c1,l,c);add(c1,r+1,-c);
        add(c2,l,-c*(l-1));add(c2,r+1,c*r);
    }
    lon pre(lon i){
        if(!i)return 0;
        return sum(c1,i)*i+sum(c2,i);
    }
    lon query(lon l,lon r){
        return pre(r)-pre(l-1);
    }
    void solve(lon head,lon tail,lon l,lon r){
        if(head>tail) return;
        if(l==r){
            for(lon i=head;i<=tail;i++)
                if(a[i].tp==2) ans[a[i].id]=l;
            return;
        }
        lon mid=l+r>>1;
        lon l1=head,l2=tail;
        for(lon i=head;i<=tail;i++){
            if(a[i].tp==1){
                if(a[i].c<=mid) q[l1++]=a[i];
                else q[l2--]=a[i],modify(a[i].l,a[i].r,1);
            }
            else {
                lon cnt=query(a[i].l,a[i].r);
                if(cnt<a[i].c){
                    a[i].c-=cnt;
                    q[l1++]=a[i];
                }
                else q[l2--]=a[i];
            }
        }
        reverse(q+l2+1,q+tail+1);
        for(lon i=head;i<=tail;i++){
            a[i]=q[i];
            if(a[i].tp==1&&a[i].c>mid)
                modify(a[i].l,a[i].r,-1);
        }
        solve(head,l1-1,l,mid);
        solve(l1,tail,mid+1,r);
    }
    int main(){
        scanf("%lld%lld",&n,&m);
        for(lon i=1;i<=m;i++){
            scanf("%lld%lld%lld%lld",&a[i].tp,&a[i].l,&a[i].r,&a[i].c);
            a[i].id=i;
            if(a[i].tp==2) has[i]=1;
        }
        solve(1,m,1,n);
        for(lon i=1;i<=m;i++)
            if(has[i])printf("%lld
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    李永乐,皇帝的新衣背后,共有知识和公共知识
    汇率原理
    mybatis pageHelper 分页插件使用
    oracle中的exists 和not exists 用法详解
    Webservice入门简单实例
    java-可逆加密算法
    idea 卡顿问题
    idea svn操作
    HttpServletrequest 与HttpServletResponse总结
    Spring boot中应用jpa jpa用法
  • 原文地址:https://www.cnblogs.com/harden/p/6426608.html
Copyright © 2011-2022 走看看