首页 > 其他分享 >CodeForces-808#D 题解

CodeForces-808#D 题解

时间:2024-08-03 19:16:58浏览次数:19  
标签:int 题解 s1 样例 CodeForces 808 s2 include define

思路分析

分析样例 1:

3
1 3 2

原数组被分成 13 2 两部分,将 2 移到左边即可。

我们设左边部分的和为 \(s1\),右边为 \(s2\),可以发现对于任何分割方式,只有满足 \(s1 \pm x=s2 \mp x\) 才可以继续讨论答案是否成立。

推论 1:由于 \(x \in a\)(\(a\) 为题目所给数列),因此 \(| \ s1-s2 \ |\equiv 0 \ (\ \bmod{ \ 2} \ )\)(换句话说,\(s1\) 和 \(s2\) 的差值必然是偶数)。

推论 2:只有当 \(\dfrac{| \ s1-s2 \ |}{2} \in a\) 时,才能成立。

我们枚举 \(p \in \{0 \ , \ n+1\}\),得出区间 \(a_{[\ 1 \ ,\ p \ ]}\)、\(a_{[\ p+1\ ,\ n\ ]}\) 之和,根据以上推论编写代码,可以用桶查询 \(\dfrac{| \ s1-s2 \ |}{2}\) 是否在原数列。

但真的如此吗?

考虑下面的样例:

5
1 2 2 5 4

这本来应该是 NO 的,但如果你只按照上述所说很有可能会输出 YES

按照上面所述,你的程序在将原数列分割成 1 2 25 4 时,\(\dfrac{| \ s1-s2 \ |}{2}\) 为 2,而 2 在桶中是可以被找到的,也就是说,你的程序认为从右边可以往左边移动一个 2,这样就成立了。

再仔细看看样例,2 分明在左边,右边是没有 2 的。

没错,你还要判断当应该从某一边移动数字时,你要判断该数字是否在这一边。

以上就是本道题的思路。如若存在常识性错误,请踢本蒟蒻。

代码实现

#define by_wanguan
#include<iostream>
#include<map>
#include<vector>
#define int long long
#define pb emplace_back
#define end cout<<"YES",exit(0)
using namespace std;
const int N=1e5+7;
int n,a[N],sum,p,s1,s2;
map<int,vector<int>> vis;
inline int abs(int &a,int &b){
  if(a>b) return a-b;
  else return b-a;
} 
signed main(){
  ios::sync_with_stdio(false),cin.tie(0);
  cin>>n;
  for(int i=1;i<=n;i++)
    cin>>a[i],sum+=a[i],vis[a[i]].pb(i);
    //记录a中a[i]出现的位置,方便后续判断abs(s2-s1)/2是否在区间内
  s2=sum,s1=0;
  for(p=0;p<=n+1;p++){//枚举左右区间分界线
    s1+=a[p],s2-=a[p];
    if(abs(s2-s1)%2!=0) continue;
    if(s1==s2) end;
    auto &pe=vis[abs(s2-s1)/2];
    if(s1<s2)
      {if(!pe.empty()&&pe.back()>p) end;}
      //由于上面的位置记录时单调的,只需要取最靠后面的位置就能判断右区间内是否有abs(s2-s1)/2
      //下面同理
    if(s1>s2)
      {if(!pe.empty()&&pe.front()<=p) end;}
  }
  cout<<"NO";
}

千万不要用 unordered_map,你会后悔的,警钟长鸣。

喵。

标签:int,题解,s1,样例,CodeForces,808,s2,include,define
From: https://www.cnblogs.com/wanguan/p/18340922

相关文章

  • 洛谷 统计天数 + 语句解析 题解
    题目:P1567统计天数P1597语句解析第一道:P1567统计天数题目描述炎热的夏日,KC非常的不爽。他宁可忍受北极的寒冷,也不愿忍受厦门的夏天。最近,他开始研究天气的变化。他希望用研究的结果预测未来的天气。经历千辛万苦,他收集了连续 N(1≤N≤10^6)天的最高气温数据。现在......
  • AGC064B 题解
    设红色的点值为0,蓝色为1。注意到,如果有一条边的颜色和两端点同色,一定可以选。例子:选择和两端点同色的边。又发现,如果存在一个\(sz>1\)的合法连通块,无论和其他点怎么连,原来的这个连通块内的点一定合法。有注意到形如\(0\xleftrightarrow10,1\xleftrightarrow01\)类......
  • P9351 题解
    P9351思路观察到一次覆盖操作相当于\((u,v)\)向\((u,v)\)为中心的一个矩形挖去四个角中每个点连代价为\(1\)的边。因为\(r\lec\),\(r\le\sqrt{rc}\)。暴力是01bfs,到每个点处理覆盖操作时枚举行一边,用\(n\)个并查集维护每行没有被删去的后继。对于每个点需要枚举\(......
  • 20240803题解
    话说T3都把式子推出来了结果忘记差分约束怎么写了。光线(light)题面:有\(n\)个玻璃板,第\(i\)个玻璃板的透光率为\(a_i\%\),反射率为\(b_i\%\),有大小为\(1\)个单位的一束光从第\(1\)个玻璃板开始,有多少光能穿透\(n\)层玻璃板。题解:考虑\(n=2\)时,可以简单算出两个玻璃板组合后的反......
  • 第三次测试题解
    问题F:求多个数的最大公约数multigcd[1*]:`#includeincludeincludeincludeusingnamespacestd;intfun(inta,intb){returnb==0?a:fun(b,a%b);}intmain(){intn;cin>>n;vectora(n+1,0);for(inti=1;i<=n;i++)scanf("%d",&a[i]);intans......
  • 镜面质数 题解
    题目id:20313题目描述如果一个质数镜像反转(即将该数各个位上数字反转)后仍然是质数,那么就称这个质数为镜像质数。例如质数\(13\)反转后为\(31\),则\(13\)为一个镜像质数。现在给定一个整数\(N\),请求出整数\(1\simN\)范围内有几个镜像质数。注意:求范围内的镜像质数时,质数和镜像反......
  • CF1946F Nobody is needed 题解
    Nobodyisneeded推销我的洛谷博客。题意多组数据。给定一个长度为\(n\)的排列\(a\),你需要回答\(q\)组询问,每组询问给出\(l,r\),求有多少个子序列\(t\)使得:\(l\leqslantt_1<t_2<\cdots<t_k\leqslantr\)。\(a_{t_i}|a_{t_{i+1}}(1\leqslanti<k)\)......
  • NSSCTF Web 题解 Write up
    NSSCTFWeb题解Writeup一、Do_you_know_http1、开题2、分析页面显示请使用“WLLM”浏览器,我没听说过“WLLM”浏览器,那首先去User-Agent修改访问的浏览器。用HackBar分析,将UA的值改成WLLM。用EXECUTE请求页面显示你只可以在本地正常阅读,并给出了ip。那简单,还是用HackB......
  • AGC013B 题解
    注意到只要随便dfs,如果没有可以走的点,说明这个端点满足要求。因为有两个端点,所以从同一个点开始搜两次,拼在一起就行了。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1e5+5;vector<int>e[N];intn,m;boolvis[N];voiddfs(in......
  • AGC009B 题解
    注意到如果把每一对胜者败者连边,可以得到一颗树:(例子)但是因为胜者每次只能和一个败者打,所以要用类似多叉转二叉的方法,让有不止一个孩子的节点变成有一个孩子和一个虚点。如图,原来\(1\)有三个儿子\(2,3,4\),通过转换,变成了上图。上图可以直接变成对战图(\(x2\tox1\to1)\):(原......