1. 程式人生 > 其它 >[CF1478C] Nezzar and Symmetric Array

[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;
}