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

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

    N,M<=50000,N,M<=50000
    a<=b<=N
    1操作中abs(c)<=N
    2操作中c<=Maxlongint


    之前用树套树抄过一次...然而我并不适合写那玩意儿...

    加上时间序的整体二分

    普通的整体二分先处理了所有$[l,mid]$的影响因子在计算询问的答案来分组

    这里要按时间序来处理影响因子和询问

    可以把时间放在第一维,反正二分的时候要按权值(答案)分成两部分

    然后需要区间加和区间求和,可以用树状数组

    数据太坑了还要$unsigned int$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=5e5+5;
    typedef long long ll;
    typedef unsigned int uint;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    int n,m;
    int CL;
    struct BIT{
        uint c[N],mark[N];
        inline int lowbit(int x){return x&-x;}
        inline void add(int p,int v){
            for(;p<=n;p+=lowbit(p)){ 
                if(mark[p]==CL) c[p]+=v;
                else mark[p]=CL,c[p]=v;
            }
        }
        inline uint sum(int p){
            uint re=0;
            for(;p;p-=lowbit(p)) 
                if(mark[p]==CL) re+=c[p];
            return re;
        }
        inline uint que(int l,int r){
            return sum(r)-sum(l-1);
        }
    }c1,c2;
    inline void add(int l,int r){
        c1.add(l,1);c1.add(r+1,-1);
        c2.add(l,l);c2.add(r+1,-(r+1));
    }
    inline uint que(int l,int r){
        return (r-l+1)*c1.que(1,l)+(r+1)*c1.que(l+1,r)-c2.que(l+1,r);
    }
    struct Operation{
        int op,l,r,k;
    }a[N];
    int id[N],t1[N],t2[N];
    uint cur[N],ans[N];
    void Sol(int l,int r,int ql,int qr){//printf("Sol %d %d %d %d
    ",l,r,ql,qr);
        if(ql>qr) return;
        if(l==r){
            for(int i=ql;i<=qr;i++)
                if(a[id[i]].op==2) ans[id[i]]=l;
            return;
        }
        int mid=(l+r)>>1,p1=0,p2=0;
        CL++;
        for(int i=ql;i<=qr;i++){
            int _=i;i=id[i];
            if(a[i].op==1){
                if(a[i].k<=mid) t1[++p1]=i;
                else add(a[i].l,a[i].r),t2[++p2]=i;
            }else{
                uint s=cur[i]+que(a[i].l,a[i].r);
                if(s<a[i].k) cur[i]=s,t1[++p1]=i;
                else t2[++p2]=i;
            }
            i=_;
        }
        for(int i=1;i<=p1;i++) id[ql+i-1]=t1[i];
        for(int i=1;i<=p2;i++) id[ql+p1+i-1]=t2[i];
        Sol(l,mid,ql,ql+p1-1);Sol(mid+1,r,ql+p1,qr);
    }
    int main(){
        freopen("in","r",stdin);
        n=read();m=read();
        for(int i=1;i<=m;i++){
            a[i].op=read(),a[i].l=read(),a[i].r=read(),a[i].k=read();
            id[i]=i;
        }
        Sol(1,n,1,m);
        for(int i=1;i<=m;i++) if(a[i].op==2) printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    SSH2练习中问题之org.apache.jasper.JasperException: /findAllProductions_list.jsp(31,1) TLD又はタグファイル中のattribute指示子に従って属性itemsはどんな式も受け付けません解决方案
    关于HibernateTempleate模版很多代码可以直接使用,是开发人员不可多得选择
    Java实现权限控制之2
    struts 之 constant
    JSTL表达式之<c:forEach>
    关于事后检查和确认
    关于删除
    jcommander 解析boolean参数
    多线程
    关于proto文件的更新
  • 原文地址:https://www.cnblogs.com/candy99/p/6457913.html
Copyright © 2011-2022 走看看