• bzoj5057: 区间k小值5


    Description

    有n(n<=30000)个位置,q(q<=30000)个操作,操作有两种。一. 1 l r a b 表示在第l个位置到第r个位置,每个位
    置加入a到b之间的所有数,一开始所有位置为空。(1<=l<=r<=n,1<=a<=b<=n)二. 2 l r k 表示询问从第l个位置到
    第r个位置,第k小的数是多少。(1<=l<=r<=n,1<=k<=n*n*q,保证k合法)

    Input

    第一行两个数n和q。
    接下来q行,每行为1 l r a b或2 l r k。
    保证第一次操作为操作一。
    测试数据均为随机产生。

    Output

    输出每个询问的结果

    在线可以用标记永久化的线段树套树状数组达到O(nlog^2n)的复杂度。由于此题可以离线,用整体二分代替线段树将所有修改和询问一起处理,处理方法和线段树相同,渐进时间复杂度不变但节省了空间。

    #include<bits/stdc++.h>
    const int N=30007;
    typedef long long i64;
    char ib[N*100],*ip=ib;
    template<class T>
    T _(){
        T x=0;
        while(*ip<48)++ip;
        while(*ip>47)x=x*10+*ip++-48;
        return x;
    }
    int n,q,tk=1,as[N];
    struct node{
        int ed;
        i64 s1,s2,e1,e2;
    }bit[N];
    void inc(int x,i64 y){
        i64 z=y*(1-x);
        for(int w=x;w<=n;w+=w&-w){
            node&b=bit[w];
            if(b.ed!=tk)b=(node){tk,0,0,0,0};
            b.s1+=y;
            b.s2+=z;
        }
    }
    void incx(int x,i64 y){
        i64 z=y*(1-x);
        for(int w=x;w<=n;w+=w&-w){
            node&b=bit[w];
            if(b.ed!=tk)b=(node){tk,0,0,0,0};
            b.e1+=y;
            b.e2+=z;
        }
    }
    i64 sum(int x,i64&ret){
        i64 s1=0,s2=0,e1=0,e2=0;
        for(int w=x;w;w-=w&-w)if(bit[w].ed==tk){
            node&b=bit[w];
            s1+=b.s1;
            s2+=b.s2;
            e1+=b.e1;
            e2+=b.e2;
        }
        ret=e1*x+e2;
        return s1*x+s2;
    }
    struct oper{
        int l,r,a,b,id;
    }os[N*50],*op=os,*op2;
    struct Q{
        int l,r,id;
        i64 k,ka;
    }qs[N*50],*qp=qs,*qp2;
    int min(int a,int b){return a<b?a:b;}
    int max(int a,int b){return a>b?a:b;}
    void solve(int l,int r,oper*lo,oper*ro,Q*lq,Q*rq){
        if(lq==rq)return;
        if(l==r){
            for(;lq!=rq;as[lq++->id]=l);
        }else{
            int m=(l+r)>>1;
            ++tk;
            oper*p01=op,*p02=op2;
            Q*q01=qp,*q02=qp2;
            for(;lq!=rq;++lq){
                for(;lo!=ro&&lo->id<=lq->id;++lo){
                    if(lo->a<=l&&lo->b>=r){
                        incx(lo->l,1);
                        incx(lo->r+1,-1);
                    }else{
                        int c=min(lo->b,m)-max(lo->a,l)+1;
                        if(c>0){
                            inc(lo->l,c);
                            inc(lo->r+1,-c);
                        }
                        if(lo->a<=m)*op++=*lo;
                        if(lo->b>m)*op2++=*lo;
                    }
                }
                i64 v1,v2;
                i64 ls=sum(lq->r,v1)-sum(lq->l-1,v2);
                lq->ka+=v1-v2;
                ls+=lq->ka*(m-l+1);
                if(ls<lq->k)lq->k-=ls,*qp2++=*lq;
                else *qp++=*lq;
            }
            oper*p1=op,*p2=op2;
            Q*q1=qp,*q2=qp2;
            solve(l,m,p01,p1,q01,q1);
            solve(m+1,r,p02,p2,q02,q2);
        }
    }
    int main(){
        fread(ib,1,sizeof(ib),stdin);
        n=_<int>(),q=_<int>();
        int qc=0;
        for(int i=1;i<=q;++i){
            if(_<int>()==1){
                int l=_<int>(),r=_<int>(),a=_<int>(),b=_<int>();
                *op++=(oper){l,r,a,b,qc};
            }else{
                int l=_<int>(),r=_<int>();
                i64 k=_<i64>();
                *qp++=(Q){l,r,qc++,k,0};
            }
        }
        op2=op+N*25;
        qp2=qp+N*25;
        solve(1,n,os,op,qs,qp);
        for(int i=0;i<qc;++i)printf("%d
    ",as[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    HTML5 Canvas编写五彩连珠(1):预览
    SQL SERVER BI 入门:(2) Analysis Service 应用
    HTML5 Canvas编写五彩连珠(6):试玩
    HTML5 Canvas编写五彩连珠(4):动画
    HTML5 Canvas编写五彩连珠(3):设计
    SQL SERVER BI 入门:(1)安装与基础概念
    HTML5 Canvas编写五彩连珠(2):画图
    pip报错“ModuleNotFoundError: No module named 'pip'”
    eWebEditor在ie8下不可用的问题
    推荐:解析“extern”
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7690357.html
Copyright © 2020-2023  润新知