1 条题解
-
0
自动搬运
来自洛谷,原作者为

Sweet_2013
今夕是何年? | 234粉爆我妹的照片,求关 | 互关条件 /training/813543搬运于
2025-08-24 23:16:46,当前版本为作者最后更新于2025-05-29 16:37:09,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意:给定一个序列,可以进行若干次操作。每次操作选择两个不同的下标 和 ,将 加 , 减 ,最后要让序列的前缀和之和等于后缀和之和,求最小的操作次数。如果无法实现,输出 。
假设前缀和之和为 ,后缀和之和为 ,题目就可以这么做:
- 求出序列的前缀和和后缀和。
- 每次选择 和 后并操作,这种操作不会改变序列的总和,因为 和 是可以互相抵消的。但会影响 和 的差值:在位置 加 对 的影响是 ,在位置 减 对 的影响是 。所以,每次操作总共对 的影响就是两式相减,得到答案是 ,最大可能的单次操作影响是 。
- 答案计算:
- 如果 为奇数,那么一定无解,因为每次操作改变 的量为偶数,所以 必须是偶数才能通过操作变为 。
- 否则,答案就是 ,因为每次操作最多可以调整 的差值。
代码:
#include<bits/stdc++.h> using namespace std; int n, a[1000005]; long long s, t, p, s1;//p 是前缀和的累加器,s1 是后缀和的累加器,s 是前缀和之和,t 是后缀和之和。 int main() { cin>> n; for(int i=0;i<n;i++) cin>> a[i]; if(n==1) { cout<<0; return 0; }//特判,n 为 1,就说明 S 和 T 已经相同了,所以是操作 0 次。 for(int i=0;i<n;i++) { p+=a[i]; s+=p; }//计算前缀和。 for(int i=n-1;i>=0;i--) { s1+=a[i]; t+=s1; }//计算后缀和。 if((s-t)%2!=0) cout<<-1;// S-T 为奇数,但每次操作变化的数为偶数,所以肯定无解。 else cout<<(abs(s-t)+(2*n-2)-1)/(2*n-2); return 0; }
- 1
信息
- ID
- 11097
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者