zoukankan      html  css  js  c++  java
  • 【bzoj4293】【PA2015】Siano

    如题,首先可以考虑相对大小是不变的。

    那么先sort,之后每次在线段树上二分即可。

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int N=500010;
    int n,m;
    ll a[N],d[N],b[N];
    struct Segment_Tree{
    #define lson (o<<1)
    #define rson (o<<1|1)
        ll addv[N<<2],sumv[N<<2],suma[N<<2],maxv[N<<2],setv[N<<2];
        inline void pushup(int o){
            sumv[o]=sumv[lson]+sumv[rson];
            maxv[o]=max(maxv[lson],maxv[rson]);
        }
        inline void pushdown(int o,int l,int r){
            int mid=(l+r)>>1;
            if(setv[o]!=-1){
                maxv[lson]=setv[o];maxv[rson]=setv[o];
                setv[lson]=setv[o];setv[rson]=setv[o];
                sumv[lson]=1LL*setv[o]*(mid-l+1);
                sumv[rson]=1LL*setv[o]*(r-mid);
                addv[lson]=0;addv[rson]=0;setv[o]=-1;
            }
            if(addv[o]){
                sumv[lson]+=addv[o]*suma[lson];sumv[rson]+=addv[o]*suma[rson];
                maxv[lson]+=1LL*a[mid]*addv[o];maxv[rson]+=1LL*a[r]*addv[o];
                addv[lson]+=addv[o];addv[rson]+=addv[o];
                addv[o]=0;
            }
        }
        inline void build(int o,int l,int r){
            setv[o]=-1;
            if(l==r){suma[o]=a[l];return;}
            int mid=(l+r)>>1;
            build(lson,l,mid);build(rson,mid+1,r);
            suma[o]=suma[lson]+suma[rson];
        }
        ll find(int o,int l,int r,ll v){
            if(l==r){if(maxv[o]>=v)return l;else return -1;}
            pushdown(o,l,r);
            int mid=(l+r)>>1;
            if(maxv[lson]>=v)return find(lson,l,mid,v);else return find(rson,mid+1,r,v);
        }
        ll querysum(int o,int l,int r,int ql,int qr){
            if(ql<=l&&r<=qr)return sumv[o];
            pushdown(o,l,r);int mid=(l+r)>>1;;ll ans=0;
            if(ql<=mid)ans+=querysum(lson,l,mid,ql,qr);
            if(qr>mid)ans+=querysum(rson,mid+1,r,ql,qr);
            return ans;
        }
        inline void change(int o,int l,int r,int ql,int qr,ll v){
            if(ql<=l&&r<=qr){
                maxv[o]=setv[o]=v;sumv[o]=1LL*v*(r-l+1);
                addv[o]=0;return;
            }
            pushdown(o,l,r);int mid=(l+r)>>1;
            if(ql<=mid)change(lson,l,mid,ql,qr,v);
            if(qr>mid)change(rson,mid+1,r,ql,qr,v);
            pushup(o);
        }
    }T;
    inline ll read(){
        ll f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++)a[i]=read();
        sort(a+1,a+n+1);
        T.build(1,1,n);
        for(int i=1;i<=m;i++){
            d[i]=read();b[i]=read();
            T.sumv[1]+=T.suma[1]*(d[i]-d[i-1]);T.maxv[1]+=1LL*a[n]*(d[i]-d[i-1]);
            T.addv[1]=d[i]-d[i-1];ll t=T.find(1,1,n,b[i]);
            if(t==-1){puts("0");continue;}
            ll ans1=T.querysum(1,1,n,t,n);T.change(1,1,n,t,n,b[i]);
            ll ans2=T.querysum(1,1,n,t,n);printf("%lld
    ",ans1-ans2);
        }
    }
  • 相关阅读:
    POJ3122贪心或者二分(分蛋糕)
    POJ2118基础矩阵快速幂
    POJ2118基础矩阵快速幂
    POJ1328贪心放雷达
    POJ1328贪心放雷达
    hdu4642博弈(矩阵)
    hdu4642博弈(矩阵)
    POJ1042 贪心钓鱼
    POJ3160强连通+spfa最长路(不错)
    POJ3114强连通+spfa
  • 原文地址:https://www.cnblogs.com/zcysky/p/7462192.html
Copyright © 2011-2022 走看看