【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\n",ans1-ans2);
    }
}

 

posted @ 2017-09-01 11:00  zcysky  阅读(439)  评论(0编辑  收藏  举报