题目大意

给定你一个长为\(n\)的序列,问能否在最多一次取出某一元素然后插入到某一点后可以将整个序列分成两段使得其两段的元素之和相同.

\(n \leq 10^5\)

题解

发现插入操作实际上是让某一个元素与端点周围的元素交换。

维护一个支持插入和查找元素是否存在的ds即可.

#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(ll &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 100010;
ll a[maxn],pre[maxn],suf[maxn];
multiset<ll>S;
int main(){
ll n;read(n);
rep(i,1,n) read(a[i]),pre[i] = pre[i-1] + a[i];
per(i,n,1) suf[i] = suf[i+1] + a[i];
rep(i,1,n){
S.insert(a[i]);
if(pre[i] == suf[i+1]){
puts("YES");
return 0;
}
ll x = pre[i] - suf[i+1] + 2LL*a[i+1];
if(x&1) continue;
x >>= 1;
if(S.count(x) != 0){
puts("YES");
return 0;
}
}
S.clear();
per(i,n,1){
S.insert(a[i]);
ll x = suf[i] - pre[i-1] + 2LL*a[i-1];
if(x&1) continue;
x >>= 1;
if(S.count(x) != 0){
puts("YES");
return 0;
}
}
puts("NO");
return 0;
}

最新文章

  1. eclipse的几个快捷键
  2. java jinfo命令详解
  3. Monkeyrunner脚本中component快速定位方法
  4. Android 定时器
  5. MIME(Multipurpose Internet Mail Extensions)的简介
  6. Objective-c复制对象的概念
  7. hdu3231 拓扑序
  8. Linux 64位编译\链接32位程序
  9. @JoinTable和@JoinColumn
  10. MYSQL中取当前年份的第一天和当前周,月,季度的第一天/最后一天
  11. Android开发之漫漫长途 Ⅴ——Activity的显示之ViewRootImpl的PreMeasure、WindowLayout、EndMeasure、Layout、Draw
  12. 可等待计时器添加APC测试
  13. 阿里云API网关(13)请求身份识别:客户端请求签名和服务网关请求签名
  14. Jmeter JDBC Connection Configuration 链接失败,提示Error preloading the connection pool
  15. python面向对象三大特性之继承
  16. C# windows GDI+仿画图 绘图程序设计
  17. 创建 .m2 文件夹
  18. C# Azure 用Webhook添加警报规则
  19. hive 0.12.0版本 问题及注意事项
  20. ZT C语言实现字符串倒序

热门文章

  1. Vosio秘钥
  2. vscode使用vue中的v-for提示错误
  3. Array.asList:数组转list
  4. Android签名机制之---签名过程详解
  5. jQuery计算器插件
  6. vRO 7 添加RestHost证书报错
  7. Eclipse4.2安装样式插件
  8. HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)
  9. Flume-NG启动过程源码分析(三)(原创)
  10. 实例说明Java中的null(转)