「NOIP2018 普及组」 龙虎斗
题意
一条直线上有 \(n\) 个兵营,相邻的两个点距离为 \(1\),第 \(i\) 个点上初始有 \(c_i\) 个工兵。
第 \(m\) 个兵营左侧为 \(1\) 号势力,右侧为 \(2\) 号势力,它本身不属于任何势力。
定义一个兵营的“气势”为它的工兵数乘它与 \(m\) 号兵营的距离。
一个势力的“气势和”为每个点的“气势”之和。
有 \(s_1\) 个工兵出现在 \(p\) 号兵营,求把 \(s_2\) 个工兵放在哪一个兵营能让两个势力的“气势和”差距最小。
分析
先把两个势力的“气势和”计算好,然后枚举放在哪一个兵营。
记录最小值和产生最小值的位置,若当前值严格小于最小值就更新。
Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
typedef __int128_t int128;
using namespace std;
// static char buf[100],*p1=buf,*p2=buf,obuf[100],*p3=obuf;
// #define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++
// #define putchar(x) (p3-obuf<100)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count());
#define dbg(x) cout<<#x<<": "<<x<<"\n"
#define usetime() printf("time: %.3lfs\n",clock()*1.0/CLOCKS_PER_SEC)
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
inline void write(ll x){if(!x){putchar(48);putchar('\n');return;}short top=0,s[40];if(x<0)x=-x,putchar(45);while(x)s[top++]=x%10^48,x/=10;while(top--)putchar(s[top]);putchar('\n');}
namespace tobe{
const ll maxn=2e5+5,mod=998244353;
ll n,c[maxn],m,p,s1,s2;
inline void mian(){
n=read();
for(ll i=1;i<=n;++i)c[i]=read();
m=read(),p=read(),s1=read(),s2=read();
c[p]+=s1;
ll cnt1=0,cnt2=0;
for(ll i=1;i<m;++i)cnt1+=c[i]*(m-i);
for(ll i=m+1;i<=n;++i)cnt2+=c[i]*(i-m);
ll ans=0,mn=INT_MAX;
for(ll i=1;i<=n;++i){
if(i<m){
ll now=abs(cnt1+s2*(m-i)-cnt2);
if(mn>now)mn=now,ans=i;
}
else if(i>m){
ll now=abs(cnt2+s2*(i-m)-cnt1);
if(mn>now)mn=now,ans=i;
}
else{
ll now=abs(cnt1-cnt2);
if(mn>now)mn=now,ans=i;
}
}write(ans);
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ll t=1;
while(t--)tobe::mian();
// fwrite(obuf,p3-obuf,1,stdout);
return 0;
}

浙公网安备 33010602011771号