CF1478A - Nezzar and Colorful Ball(数学)

CF1478A - Nezzar and Colorful Balls

Solution

真不戳,这 A A A题真不戳,我直接好家伙。

讲一下我搞了半个小时的垃圾做法 (好吧后来看了看标算好像和我是一样的)
大概是容易发现你两个数 ( x , y ) (x,y) (x,y)做来做去最后一定是 a x − ( a − 1 ) y ax-(a-1)y ax(a1)y的形式,然后再继续搞一搞三个数的,最后你发现每个数的贡献次数之和等于 1 1 1,于是问题变成了这样子:
给定 a 1 . . . a n a_1...a_n a1...an,问是否存在一个 x 1 . . . x n x_1...x_n x1...xn,使得:
∑ i = 1 n x i = 1 ∑ i = 1 n a i x i = k \sum_{i=1}^n x_i=1\\ \sum_{i=1}^n a_ix_i=k i=1nxi=1i=1naixi=k
从上面的式子可知:
x n = 1 − ∑ i = 1 n − 1 x i x_n=1-\sum_{i=1}^{n-1} x_i xn=1i=1n1xi
代入下面的式子:
∑ i = 1 n a i x i = ∑ i = 1 n − 1 a i x i + a n ( 1 − ∑ i = 1 n − 1 x i ) = ∑ i = 1 n − 1 ( a i − a n ) x i + a n \sum_{i=1}^na_ix_i=\sum_{i=1}^{n-1}a_ix_i+a_n(1-\sum_{i=1}^{n-1}x_i)=\sum_{i=1}^{n-1}(a_i-a_n)x_i+a_n i=1naixi=i=1n1aixi+an(1i=1n1xi)=i=1n1(aian)xi+an
于是我们有:
∑ i = 1 n − 1 ( a i − a n ) x i = k − a n \sum_{i=1}^{n-1}(a_i-a_n)x_i=k-a_n i=1n1(aian)xi=kan
那么就是一个 ∑ i a i x i = b \sum_i a_ix_i=b iaixi=b的裴蜀定理的形式,有解的条件就是:
g c d ( a i − a n ) ∣ k − a n gcd(a_i-a_n)|k-a_n gcd(aian)kan
注意这里为了避免 a i − a n < 0 a_i-a_n<0 aian<0,我们给降序序列排序,于是 a n a_n an为最小值。

时间复杂度 O ( n l g n ) O(nlgn) O(nlgn)

然后就没了,对,就没了。我真是个铁憨憨。

Code

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
//#include <unordered_set>
//#include <unordered_map>
//#include <bits/stdc++.h>

#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define fi first
#define se second

using namespace std;

template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; }
template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }

typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pair<int,int> PR;
typedef vector<int> VI;

const lod eps=1e-11;
const lod pi=acos(-1);
const int oo=1<<30;
const ll loo=1ll<<62;
const int mods=998244353;
const int MAXN=600005;
const int INF=0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline ll read()
{
	ll f=1,x=0; char c=getchar();
	while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }
	while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
	return x*f;
}
ll a[MAXN];
ll gcd(ll x,ll y) { return y==0?x:gcd(y,x%y); }
signed main()
{
	int Case=read();
	while (Case--)
	{
		int n=read(); ll k=read(),g=0;
		for (int i=1;i<=n;i++) a[i]=read();
		sort(a+1,a+n+1,greater<ll>());
		for (int i=1;i<n;i++) a[i]-=a[n]; k-=a[n];
		for (int i=1;i<n;i++) g=gcd(g,a[i]);
		puts(k%g==0?"YES":"NO");
	} 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值