[CF1478C] Nezzar and Symmetric Array

前言

我可以说这道题是这场 Div2 最难的题吗?就这道题挂过,还挂了 \(3\) 次!

有趣的做题时间(单位:分钟):

\(A:3; B:10; C:86; D:11; E:22;\)

F 没时间做了,痛失AK。1700 的难度你是在逗我?

题目

CF

洛谷

题目大意: 洛谷

注意 \(a_i\) 两两不同。

讲解

首先有一些很显然的结论: 每种数字出现次数一定是偶数次,并且一定是偶数,互为相反数的两个数 \(d_i\) 一定相等。

这些结论随便玩一玩就可以想到。

为了方便讲解,我们令 \(-a_n<...<-a_2<-a_1<0<a_1<a_2<...<a_n\)

然后我们开始对题意进行转换:将 \(a_i\) 放在数轴上,那么 \(|a_i-a_j|\) 即为两点之间的距离,\(d_i\) 即为 \(i\) 与其它所有点的距离和。

显然,越中间的 \(a_i\) 对应的 \(d_i\) 越小,为方便处理,我们可以对 \(d_i\) 进行排序,然后砍掉相同的一半。

我们直接试图将 \(a_i\) 构造出来,最好下手的是 \(a_n\)

因为有 \(-a_i\) 的存在,我们在数轴上无论怎么移动 \(a_i\),对 \(d_n\) 都是没有影响的!

所以此时 \(a_n=\frac{d_n}{2\times n}\),当然,如果不整除就无解。

那么 \(a_{n-1}\) 怎么处理呢?\(a_n\) 会对 \(a_{n-1}\) 产生影响的啊!

考虑 \(a_n\)\(d_{n-1}\) 的影响是什么:\(-a_n\)\(a_n\)\(a_{n-1}\) 夹在中间,所以 \(d_{n-1}\) 只需要减去 \(2\times a_n\) 就可以按上述方法接着做了。

需要满足的条件是 \(a_i>0,i\in[1,n]\)\(a_i<a_{i+1},i\in[1,n-1]\)。当然,上面那个 \(2\times n|d_n\) 也需要满足。

代码

//12252024832524
#include <cstdio>
#include <cstring>
#include <algorithm>
#define TT template<typename T>
using namespace std;

typedef long long LL;
const int MAXN = 200005;
LL n; 
LL d[MAXN],a[MAXN];

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	for(int T = Read(); T ;-- T)
	{
		n = Read();
		for(int i = 1;i <= 2*n;++ i) d[i] = Read();
		sort(d+1,d+2*n+1);
		bool f = 1;
		for(int i = 1;i <= 2*n && f;i += 2) 
			if(d[i] != d[i+1] || (d[i] & 1)) f = 0; 
		for(int i = 2;i <= 2*n;i += 2) d[i/2] = d[i];
		LL jian = 0;
		a[n+1] = 0;
		for(int i = n;i >= 1 && f;-- i)
		{
			d[i] -= jian;
			if(d[i] <= 0 || d[i] % (2*n)) {f = 0;break;}
			a[i] = d[i] / (2*n);
			if(a[i] == a[i+1]) {f = 0;break;}//pay attention to “distinct”!
			jian += 2*a[i]; 
			n--;
		}
		if(!f) {printf("NO\n");continue;}
		printf("YES\n");
	}
	return 0;
}
posted @ 2021-06-24 18:10  皮皮刘  阅读(39)  评论(0编辑  收藏  举报