Codeforces Round #698 (Div. 2) C and D
C. Nezzar and Symmetric Array
构造,从d数组可以从大往小构造唯一的a数组。
eg:\(a[ ]={-z,-y,-x,x,y,z},d[ ]=[i,i,j,j,k,k]\)(已经排好序且合法),从最大的k开始可以构造出\(z\)和\(-z\),因为其他任何数与\(z\)和\(-z\)的距离之和都为\(2*z\),易知\(z=k/(2*n)\),这样就把z和-z确定下来了。
然后对于第二大的数\(j\),它所对应的\(y\)和\(-y\)只有与\(z\)和\(-z\)连接时权值为\(2*z\),其他时候都为\(2*y\),因此把2*z减掉(这样\(j==y*(2*n-2)\)了)就可以用刚刚提到的确定d中最大数对应a的方法去求。
以此类推,对每一个d数组中的数d[x],需要先让\(d[x]-=2*(d[x+1]/cnt[x+1]+d[x+2]/cnt[x+2]...+d[n]/cnt[n])\),然后检查\(d[x]\)是否大于\(0\)并且对应的\(a=d[x]/cnt[x]\)未出现过。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
double pi = acos(-1);
const double eps = 1e-9;
const int inf = 1e9 + 7;
const int maxn = 2e5 + 10;
ll mod = 1000000007;
bool check(vector<ll>& a)
{
int len = a.size();
if (len % 2 == 0)return 0;
for (int i = 1; 2 * i < len; i++)
if (a[2 * i] != a[2 * i - 1])
return 0;
return 1;
}
map<ll, ll>mp;
int main()
{
fastio;
int t;
cin >> t;
while (t--)
{
mp.clear();
int n;
cin >> n;
vector<ll>d(2 * n + 1);
for (int i = 1; i <= 2 * n; i++)
cin >> d[i];
sort(d.begin() + 1, d.end());
if (!check(d))
{
cout << "NO" << endl;
continue;
}
for (int i = 1, j = 1; i <= n; i++, j += 2)
d[i] = d[j];
ll tmp = 0, cnt = 2 * n;
bool flag = 1;
for (int i = n; i >= 1; i--)
{
d[i] -= tmp;
//cout << d[i] << " ";
if (d[i] % cnt != 0 || d[i] <= 0 || mp[d[i] / cnt])
{
flag = 0;
break;
}
mp[d[i] / cnt] = 1;
tmp += 2 * (d[i] / cnt);
cnt -= 2;
}
if (flag)
cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
D - Nezzar and Board
①\(2*x-y\):假设\(y=x+z\),则\(2*x-y=x-z\),即每次选择两个数\(x\)和\(y\),\(y\)都会以\(x\)为轴进行翻转。
②先以k为原点,确定每个点的位置。已有数(已排序)有n-1个相互之间的距离,他们通过上述操作可以凑出的最小值为所有距离gcd在一起(更相减损的推广,这个值是可以凑出所有这些值更相减损能凑出的数的),然后去遍历一发看看有没有数可以被这个数整除。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
double pi = acos(-1);
const double eps = 1e-9;
const int inf = 1e9 + 7;
const int maxn = 2e5 + 10;
ll mod = 1000000007;
ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; }
int main()
{
fastio;
int t;
cin >> t;
while (t--)
{
ll n, k;
cin >> n >> k;
vector<ll>a(n + 1);
for (int i = 1; i <= n; i++)cin >> a[i], a[i] -= k;
sort(a.begin() + 1, a.end());
ll g = a[2] - a[1];
for (int i = 3; i <= n; i++)
g = gcd(g, a[i] - a[i - 1]);
bool flag = 0;
for (int i = 1; i <= n; i++)
if (a[i] % g == 0)
{
flag = 1;
break;
}
if (flag)
cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}