zoukankan      html  css  js  c++  java
  • bzoj 4826: [Hnoi2017]影魔

    将区间[L,R]和点对(i,j)看作平面上的点,则询问为矩形求和

    建出笛卡尔树,对应找出贡献为p1或p2的点,p1类的点总数为$O(n)$,p2类的点可以分为$O(n)$组,每组对应一条水平或竖直线段

    最后用扫描线统计一下答案

    #include<cstdio>
    #include<algorithm>
    typedef long long i64;
    const int N=200007;
    #define G *++ptr
    char buf[N*30],*ptr=buf-1;
    int _(){
        int x=0,c=G;
        while(c<48)c=G;
        while(c>47)x=x*10+c-48,c=G;
        return x;
    }
    int n,m,p1,p2,a[N],ss[N],sp=0;
    int ch[N][2],lr[N][2];
    i64 as[N];
    
    i64 kb[N][2],bit[N][2];
    void kb_add(int w,i64 k,i64 b){
        for(;w<=n;w+=w&-w){
            kb[w][0]+=k;
            kb[w][1]+=b;
        }
    }
    void kb_sum(int w,i64&_k,i64&_b){
        i64 k=0,b=0;
        for(;w;w-=w&-w){
            k+=kb[w][0];
            b+=kb[w][1];
        }
        _k=k;_b=b;
    }
    void add(int w,i64 a){
        i64 b=a*(w-1);
        for(;w<=n;w+=w&-w){
            bit[w][0]+=a;
            bit[w][1]+=b;
        }
    }
    i64 sum(int w){
        i64 a=0,b=0,w0=w;
        for(;w;w-=w&-w){
            a+=bit[w][0];
            b+=bit[w][1];
        }
        return a*w0-b;
    }
    
    struct Q{
        int x,y,id;
        bool operator<(Q w)const{return x>w.x;}
        void work(){
            i64 k,b;
            kb_sum(y,k,b);
            as[id]=sum(y)+k*x+b;
        }
    }qs[N];
    struct E{
        int x,y,tp,y2;
        bool operator<(E w)const{return x>w.x;}
        void work(){
            if(tp==0){
                kb_add(y,0,p1-p2);
            }else if(tp==1){
                add(y,p2);
                add(y2+1,-p2);
            }else if(tp==2){
                kb_add(y,-p2,i64(1+x)*p2);
            }else{
                kb_add(y,p2,i64(-x-1)*p2);
            }
        }
    }es[N*8];
    int ep=0;
    void dfs(int w){
        int lc=ch[w][0],rc=ch[w][1];
        lr[w][0]=lr[w][1]=w;
        if(lc){
            dfs(lc);
            lr[w][0]=lr[lc][0];
            es[ep++]=(E){lr[lc][1],w,2};
            es[ep++]=(E){lr[lc][0]-1,w,3};
        }
        if(rc){
            dfs(rc);
            lr[w][1]=lr[rc][1];
            es[ep++]=(E){w,lr[rc][0],1,lr[rc][1]};
        }
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin)[buf]=0;
        n=_();m=_();p1=_();p2=_();
        for(int i=1;i<=n;++i)a[i]=_();
        for(int i=1;i<=n;++i){
            ch[ss[sp]][1]=i;
            while(sp&&a[ss[sp]]<a[i]){
                int w=ss[sp--];
                ch[w][1]=ch[i][0];
                ch[i][0]=w;
                ch[ss[sp]][1]=i;
            }
            ss[++sp]=i;
        }
        dfs(ch[0][1]);
        for(int w=1;w<=n;++w){
            for(int u=ch[w][0];u;u=ch[u][1])es[ep++]=(E){u,w,0};
            for(int u=ch[w][1];u;u=ch[u][0])es[ep++]=(E){w,u,0};
        }
        std::sort(es,es+ep);
        for(int i=0;i<m;++i){
            qs[i].x=_();
            qs[i].y=_();
            qs[i].id=i;
        }
        std::sort(qs,qs+m);
        for(int i=0,j=0;i<m;++i){
            while(j<ep&&es[j].x>=qs[i].x)es[j++].work();
            qs[i].work();
        }
        for(int i=0;i<m;++i)printf("%lld
    ",as[i]);
        return 0;
    }
  • 相关阅读:
    电容
    51单片机
    三极管
    Scala 面向对象(八):特质(接口) 一
    Scala 面向对象(七):静态属性和静态方法
    Scala 面向对象(六):面向对象的特征二:继承 (一)
    Scala 面向对象(五):面向对象的特征一:封装性
    Scala 面向对象(四):import
    Scala 面向对象(三):package 包 (二)
    Scala 面向对象(二):package 包 (一) 入门
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6727641.html
Copyright © 2011-2022 走看看