Gym102268D Dates

Link
根据拟阵的理论,从大到小枚举girl,如果加入当前girl之后又完美匹配那么就选择该girl,否则就不选。
剩下的就跟Link很像了。

#include<cstdio>
#include<cctype>
#include<utility>
#include<algorithm>
#define fi first
#define se second
using i64=long long;
using pi=std::pair<int,int>;
const int N=300007;
int n,m,a[N];i64 sa[N];pi b[N];
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
struct segtree
{
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
    i64 t[N<<2],tag[N<<2];int opt;
    i64 merge(i64 x,i64 y){return opt? std::max(x,y):std::min(x,y);}
    void pushup(int p){t[p]=merge(t[ls],t[rs]);}
    void modify(int p,i64 x){t[p]+=x,tag[p]+=x;}
    void pushdown(int p){if(tag[p])modify(ls,tag[p]),modify(rs,tag[p]),tag[p]=0;}
    void update(int p,int l,int r,int L,int R,i64 x)
    {
	if(L>R||l>R||L>r) return ;
	if(L<=l&&r<=R) return modify(p,x);
	pushdown(p),update(ls,l,mid,L,R,x),update(rs,mid+1,r,L,R,x),pushup(p);
    }
    i64 query(int p,int l,int r,int L,int R)
    {
	if(L>r||l>R) return opt? (i64)-1e18:(i64)1e18;
	if(L<=l&&r<=R) return t[p];
	return pushdown(p),merge(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R));
    }
}t1,t2;
int main()
{
    int n=read(),m=read();i64 ans=0;t1.opt=1,t2.opt=0;
    for(int i=1;i<=m;++i) sa[i]=sa[i-1]+(a[i]=read());
    for(int i=1,l,r;i<=n;++i) l=read(),r=read(),b[i]={read(),i},t1.update(1,1,n,i,i,-sa[r]),t2.update(1,1,n,i,i,-sa[l-1]);
    std::sort(b+1,b+n+1,[](const pi&a,const pi&b){return a.fi>b.fi;});
    for(int i=1,x;i<=n;++i) if(x=b[i].se,t1.query(1,1,n,x,n)<t2.query(1,1,n,1,x)) ans+=b[i].fi,t1.update(1,1,n,x,n,1),t2.update(1,1,n,x+1,n,1);
    printf("%lld",ans);
}
posted @ 2020-03-14 09:57  Shiina_Mashiro  阅读(221)  评论(0编辑  收藏  举报