题解:CF2157D Billion Players Game
Hog_Dawa_IOI · · 题解
题意
一个数
解法
拜谢 Sam_Yang 提供解法。
首先一定有一个分界线
其次,如果
有一个事情是最小值要么在
现在还没有计算的贡献分为两部分,一个是
画个图:
黑色是我们已经算过的贡献(前面说的已被累加),绿色是分界线,红色是
然后发现中间那些交错的贡献稍微好算一些。由于
想让这玩意累加最大,让它们从大到小一一匹配就好了。
还有跨过
我还忘说了一件事。我们希望
这个原则在“中间那些交错的贡献”中可以被体现。
但是万一
我们就需要从
如果
最后的匹配效果长这样:
#include<cstdio>
#include<algorithm>
using namespace std;
long long ans,t,n,l,r,s[200005];
int main()
{
scanf("%lld",&t);while(t--)
{
scanf("%lld%lld%lld",&n,&l,&r),ans=0;
for(int i=1;i<=n;i++) scanf("%lld",&s[i]);
sort(s+1,s+n+1);long long ll=1,rr=n;
while(ll<=n&&s[ll]<=l) ans+=l-s[ll],ll++;
while(rr>=1&&s[rr]>=r) ans+=s[rr]-r,rr--;
ans+=min(ll-1,n-rr)*(r-l);
while(ll>n-rr+1&&ll<=rr) ans+=s[rr]-l,rr--;
while(ll<n-rr+1&&ll<=rr) ans+=r-s[ll],ll++;
while(ll<rr) ans+=s[rr]-s[ll],rr--,ll++;
printf("%lld\n",ans);
}
}