• AC日记——[Hnoi2017]影魔 bzoj 4826


    4826

    思路:

      主席树矩阵加减+单调栈预处理;

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 200005
    #define ll long long
    #define maxtree maxn*30
    class PTreeType
    {
        private:
            int ch[maxtree][2],root[maxn],tot,head[maxn],li[maxn<<1],ri[maxn<<1],E[maxn<<1],cnt,val_[maxn<<1];
            ll val[maxtree],tag[maxtree];
        public:
            void add(int &now,int pre,int l,int r,int tl,int tr,ll x)
            {
                now=++tot,val[now]=val[pre],tag[now]=tag[pre];
                val[now]+=((r<tr?r:tr)-(l>tl?l:tl)+1)*x;
                ch[now][0]=ch[pre][0],ch[now][1]=ch[pre][1];
                if(l>=tl&&r<=tr){tag[now]+=x;return;}int mid=l+r>>1;
                if(tl<=mid) add(ch[now][0],ch[pre][0],l,mid,tl,tr,x);
                if(tr>mid) add(ch[now][1],ch[pre][1],mid+1,r,tl,tr,x);
            }
            ll query(int now,int pre,int l,int r,int tl,int tr)
            {
                if(l>=tl&&r<=tr) return val[now]-val[pre];
                int mid=l+r>>1;ll res=((r<tr?r:tr)-(l>tl?l:tl)+1)*(tag[now]-tag[pre]);
                if(tl<=mid) res+=query(ch[now][0],ch[pre][0],l,mid,tl,tr);
                if(tr>mid) res+=query(ch[now][1],ch[pre][1],mid+1,r,tl,tr);
                return res;
            }
            void add(int l,int r,int size,int x,int to)
            {
                add(root[to],root[to],1,size,l,r,x);
            }
            ll query(int l,int r,int size,int now,int pre)
            {
                return query(root[now],root[pre],1,size,l,r);
            }
            void operation_add(int to,int l,int r,int pi)
            {
                E[++cnt]=head[to],li[cnt]=l,ri[cnt]=r,val_[cnt]=pi,head[to]=cnt;
            }
            void makeit(int size)
            {
                for(int i=1;i<=size;i++)
                {
                    root[i]=root[i-1];
                    for(int v=head[i];v;v=E[v])
                    {
                        add(li[v],ri[v],size,val_[v],i);
                    }
                }
            }
    };
    class PTreeType xtree,ytree;
    struct NodeType {
        int l,r;
    };
    struct NodeType ai[maxn];
    int n,m,p1,p2,ki[maxn],sta[maxn];
    inline void in(int &now)
    {
        char Cget=getchar();now=0;
        while(Cget>'9'||Cget<'0') Cget=getchar();
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    inline void in(ll &now)
    {
        char Cget=getchar();now=0;
        while(Cget>'9'||Cget<'0')Cget=getchar();
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    int main()
    {
        in(n),in(m),in(p1),in(p2);int top=0,op,l,r;ll ans;
        for(int i=1;i<=n;i++)
        {
            in(ki[i]);
            while(top&&ki[sta[top]]<ki[i]) ai[sta[top]].r=i,top--;
            ai[i].l=sta[top],sta[++top]=i;
        }
        while(top) ai[sta[top]].r=n+1,top--;
        for(int i=1;i<=n;i++)
        {
            if(ai[i].l>0&&ai[i].r<=n) xtree.operation_add(ai[i].l,ai[i].r,ai[i].r,p1);
            if(i+1<=ai[i].r-1) xtree.operation_add(ai[i].l,i+1,ai[i].r-1,p2);
            if(ai[i].l+1<=i-1) ytree.operation_add(ai[i].r,ai[i].l+1,i-1,p2);
        }
        xtree.makeit(n),ytree.makeit(n);
        while(m--)
        {
            in(l),in(r),ans=0;
            ans+=xtree.query(l,r,n,r,l-1);
            ans+=ytree.query(l,r,n,r,l-1);
            ans+=(ll)p1*(r-l);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    HTML的基本知识
    java script后续
    java script
    CSS
    DAY 33 进程理论与进程方法
    DAY 32 UDP协议、Socketserver模块,并发编程基础
    DAY 30 网络编程基础
    DAY 25多态、反射、异常处理
    DAY 24继承与组合
    DAY 23 面向对象(二)
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/7100488.html
Copyright © 2020-2023  润新知