《Nezzar and Symmetric Array》

题意注意的是,相反数必定在数组中。

首先很容易可以算出每对相反数的总差值和是一样的,所以d中的差值一定要成对出现。

且,可以发现,对于差值的计算有两种情况。

对于y,计算和-x , x的差值。

当y < x。dis = (x - y) + (y + x) = 2 * x;

当y > x。dis = (y - x) + (y + x) = 2 * y;

所以dis的总和最终必定是2的倍数,也就是说d中的值必须是偶数。

有了上面这个计算的差值,那么我们可以发现最大的数mx,它的差值和就是2 * mx * n。

第二大的数sec就是2 * (n - 1) * sec + 2 * mx,以此类推,我们就可以计算出所有原来的数。

1:在计算过程中,如果满足无法整除就说明求不出这个数,那么显然不满足。

2:因为题目中开始说明过了原数组中的数是全部不相同的,所以我们要需要判断一下求出来的数有没有重复。

3:我们上面都当x,y是正整数,所以我们求出来的数也要是正的才满足我们的递推。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e5 + 5;
const int M = 3e5 + 5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e18
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

LL d[N << 1];
int main()
{
    int ca;ca = read();
    while(ca--){
        int n;n = read();
        map<LL,int> mp;
        for(int i = 1;i <= 2 * n;++i) d[i] = read(),mp[d[i]]++;
        sort(d + 1,d + 2 * n + 1);
        int f = 0;
        for(int i = 1;i <= 2 * n;++i){
            if(mp[d[i]] % 2 != 0 || d[i] % 2 != 0) f = 1; 
        }
        LL ma = d[2 * n],sum = 0;
        if(d[2 * n] % (2 * n) != 0) f = 1;
        ma /= (2 * n);
        map<LL,int> have;
        have[ma]++;
        for(int i = 2 * n - 2;i >= 1;i -= 2){
            sum += 2 * ma;
            if((d[i] - sum) % i != 0) f = 1;
            ma = (d[i] - sum) / i;
            if(have[ma] == 1) f = 1;
            have[ma]++;
            if(ma <= 0) f = 1;
        }
        printf("%s\n",f ? "NO" : "YES");
    }
    system("pause");
    return 0;
}
View Code

 

posted @ 2021-01-29 09:15  levill  阅读(294)  评论(0编辑  收藏  举报