LOJ 2840「JOISC 2018 Day 4」糖
有趣的脑子题(可惜我没有脑子
好像也可以称为模拟费用流(?
我们考虑用链表维护这个东西 再把贡献扔到堆里贪心就好了
大概就是类似于有反悔机制的贪心?我们相当于把选中的一个打上一个-v的tag然后如果选了它旁边的就把它取消掉 也是一个打tag的思想
说起来不是很好描述 看代码可能会更好理解(?
//Love and Freedom. #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #define ll long long #define inf 20021225 #define pa pair<ll,int> #define mp make_pair #define fs first #define se second #define N 200001 using namespace std; int read() { int s=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*f; } int pre[N],nxt[N]; ll val[N]; int a[N],n; bool vis[N]; priority_queue<pa> hp; void upd(int x) { vis[x]=1; nxt[pre[x]]=nxt[x]; pre[nxt[x]]=pre[x]; } int main() { n=read(); ll ans=0; val[0]=-1ll*inf*inf; val[n+1]=-1ll*inf*inf; for(int i=1;i<=n;i++) val[i]=a[i]=read(),pre[i]=i-1,nxt[i]=i+1,hp.push(mp(val[i],i)); for(int i=1;i+i-1<=n;i++) { while(vis[hp.top().se]) hp.pop(); pa tmp=hp.top(); hp.pop(); ll v=tmp.fs; int pos=tmp.se; ans+=v; printf("%lld\n",ans); int l=pre[pos],r=nxt[pos]; val[pos]=val[l]+val[r]-val[pos]; if(l && r<=n) hp.push(mp(val[pos],pos)); upd(l); upd(r); } return 0; }