首页 > 其他 > 详细

【CF1478C】 Nezzar and Symmetric Array

时间:2021-02-05 15:07:21      阅读:45      评论:0      收藏:0      [点我收藏+]

题目链接Nezzar and Symmetric Array

题意

? 有一个数组 \(a\) ,共有 \(2n\) 个整数,且每个数互不相等,对于每个数 \(a_i\) 都能在这个数组里找到一个数 \(a_j\) 使得 \(a_i\)\(a_j\) 互为相反数,即\(a_i=-a_j\)

? 除此之外还有一个数组 \(d\) ,有 \(2n\) 个整数,每个整数 \(d_i\) 代表 \(a_i\)\(a\) 中每个元素之差的绝对值之和。

? 给你数组 \(d\) ,问你该数组 \(d\) 对应的数组 \(a\) 是否存在。


思路

? \(a\) 中每个数互不相同,且每个数都能在 \(a\) 中找到自身的相反数,也就是说数组 \(a\) 中不包含0,若包含0则 \(a\) 中的数字个数只能是奇数。

? 不仅如此,我们还能推出 $ a$ 中含有 \(n\) 个正数和 \(n\) 个负数,且这些正数和负数在数轴上关于0点对称,比如:

? 技术分享图片

?

? 假设 \(a_i\)\(a_j\) 是一对相反数,在数轴上显然 \(a_i\) 到0点的距离和 \(a_j\) 到0点的距离相等,于是,不难得到 \(a_i\)\(a_j\) 的距离是偶数。

? 两数之差的绝对值在数轴上相当于两点间的距离,所以, \(d_i\) 等于\(a_i\)\(a\) 中其他元素的距离之和,对于 \(d_i\) 的相反数,两者间的距离自然是偶数,对于 \(a\) 中其他元素 \(a_j\) ,假设 \(a_k\)\(a_j\) 的相反数,则 \(a_i\)\(a_j\) 的距离加上 \(a_i\)\(a_k\) 的距离也是偶数,偶数相加必然也是偶数。

? 于是我们得到1第个对数组 \(d\) 的要求:\(d\) 中每个数均为偶数

? 经过观察,我们可以发现对于一对相反数 \(a_i\)\(a_j\) ,其 \(d_i\)\(d_j\) 相等,又因为 \(a\) 中每个数互不相等,则可得到第2个对数组 \(d\) 的要求:\(d\) 中每个数的出现次数必定为两次



? 通过观察(玄学)发现, \(d_i\) 越小,对应的 \(a_i\) 越靠近0点, \(d_i\) 越大,对应的 \(a_i\) 越远离0点。

? 现在假设数组 \(a\) 已经按照升序排序,个人习惯,下标从1开始,其中 \(a_1\)\(a_n\) 在数轴负半轴, \(a_{n+1}\)\(a_{2n}\) 在正半轴,对于正半轴上的 \(a_i\)\(a_{i+1}\) ,对应的\(d_i\)\(d_{i+1}\) 如图:

技术分享图片

红线长度之和是 \(d_i\) , 蓝线长度之和是 \(d_{i+1}\)

? 可以发现,在两绿线两侧的红线长度之和与蓝线长度之和相等,尽在两绿线之间的红线长度和与蓝线长度和不等,于是,可以推出 \(d_{i+1}\)\(d_i\) 的差是 \(a_{i-1}\)\(a_i\) 距离的整数倍。

? 经计算可以得出 \(d_{i+1}-d_i=2i(a_{i+1}-a_i)\) ,注意此处 \(i\) 在正半轴上。

? 我们可以通过以上方法求出正半轴上所有 \(a_i\)\(a_{i+1}\) 的相对位置,因负半轴和正半轴对称,求出正半轴也相当于求出了负半轴。



? 但仅求出相对距离还不够,我们还要求出 \(a\) 中每个数的绝对位置,只需求出 \(a\) 中一个数在数轴上的绝对位置,其他数的绝对位置则可由之前算出的相对位置求出。

? 考虑在正半轴上的 \(a_{n+1}\) 和在负半轴上的 \(a_n\) ,两数互为相反数,关于0点对称,那么只要求出 \(a_n\)\(a_{n+1}\) 的距离,就可以算出 \(a_{n+1}\)\(a_n\) 到0点的距离,也就是两数的绝对位置也可以确定。

? 现在考虑如何求 \(a_{n+1}-a_n\) ,对于上面的 \(d_{i+1}-d_i=2i(a_{i+1}-a_i)\) ,此处并不适用,但我们已经知道了正半轴以及负半轴上相邻两个数的的相对位置,则可以通过这些信息推算出 \(a_{n+1}-a_n\) 的值。

? \(d_{n+1}\) 在数轴上表示如图:

技术分享图片

? 图中了绿线部分,可以用之前求出的相对位置算出,我们发现,\(d_{n+1}\) 减去这些绿线的长度,剩下的值是 \(a_{n+1}-a_n\)\(n\) 倍,由此,我们就能算出 \(a_{n+1}\) 的绝对位置。

? 因为 \(a_n\)\(a_{n+1}\) 关于0点对称,则 \(a_{n+1}-a_n\) 必定为偶数且大于0,又因为 \(a_{n+1}\) 在正半轴上,所以要求 \(a_{n+1}\) 大于0,所以可以得到两个要求:

  • \(a_{n+1}-a_n\) 是偶数
  • \(a_{n+1}\) 大于0

整理一下判断 \(a\) 是否存在的依据:

  • \(d\) 中元素均为偶数
  • \(d\) 中元素必定出现两次
  • \(a_{n+1}-a_n\) 是偶数
  • \(a_{n+1}\) 大于0

code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll d[200000+10],d1[200000+10];

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    ll t,n;
    cin>>t;
    while(t--)
    {
        ll flag=0,tot=1;
        map <ll,ll> mp;
        cin>>n;
        n<<=1;
        for(ll i=1;i<=n;i++)
        {
            cin>>d[i];
            if(d[i]&1LL)
            {
                flag=1;
            }
            mp[d[i]]++;
        }
        if(flag)
        {
            cout<<"NO"<<"\n";
            continue;
        }
        n>>=1;
        for(auto it=mp.begin();it!=mp.end();it++)
        {
            d[tot++]=it->first;
            if(it->second!=2)
            {
                flag=1;
                break;
            }
        }
        if(flag)
        {
            cout<<"NO"<<"\n";
            continue;
        }
        sort(d+1,d+1+n);
        tot=1;
        for(ll i=1;i<=n-1;i++)
        {
            ll num=d[i+1]-d[i];
            if(num&1||num%(2LL*i)!=0)
            {
                flag=1;
                break;
            }
            d1[i]=num/(2LL*i);
        }
        if(flag)
        {
            cout<<"NO"<<"\n";
            continue;
        }
        ll cnt=2,sum=0;
        for(ll i=n-1;i>=1;i--,cnt+=2)
        {
            d[1]-=cnt*d1[i];
            if(d[1]<=0)
            {
                flag=1;
                break;
            }
        }
        if(d[1]%n!=0)
            flag=1;
        else
            d[1]/=n;
        if(d[1]<=0||d[1]&1)
            flag=1;
        if(flag)
            cout<<"NO"<<"\n";
        else
            cout<<"YES"<<"\n";
    }
    return 0;
}

【CF1478C】 Nezzar and Symmetric Array

原文:https://www.cnblogs.com/zjl4785/p/14377079.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!