题目
给出一个长度为 (2n) 的数组,问是否存在一个满足条件的 (a) 数组,满足给出的 (d) 数组。((1≤n≤10^5,0≤d_i≤10^{12}))
题目链接:https://codeforces.com/contest/1478/problem/C
分析
首先,(d) 数组中的数必须是成对出现,两两相同。一开始从小的数入手,推了很久的公式都没有解决。其实,从最大的 (a_i) 入手就很好写。可以发现,有:
[a_i=frac{d_{i}-2sum_{j=i+1}^{n}{a_j}}{2i}
]
按照公式,求出 (a) ,然后按照题目条件依次判断即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll d[N],a[N];
map<ll,int>mp;
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
mp.clear();
for(int i=1;i<=2*n;i++)
scanf("%lld",&d[i]);
sort(d+1,d+1+2*n);
int f=0,cnt=0;
for(int i=1;i<=2*n;i+=2)
{
if(d[i]!=d[i+1]||d[i]%2==1)
{
f=1;
break;
}
d[++cnt]=d[i];
}
if(f==0)
{
ll sum=0;
for(int i=n;i>=1;i--)
{
if((d[i]-2*sum)%(2*i))
{
f=1;
break;
}
a[i]=(d[i]-2*sum)/(2*i);//cout<<i<<":"<<a[i]<<endl;
if(mp.count(a[i])||a[i]<=0)
{
f=1;
break;
}
mp[a[i]]=1;
sum+=a[i];
}
if(f) printf("NO
");
else printf("YES
");
}
else printf("NO
");
}
return 0;
}