Codeforces Round #360 (Div. 2) D. Remainders Game 中国剩余定理
题目链接:
题目
D. Remainders Game
time limit per test 1 second
memory limit per test 256 megabytes
问题描述
Today Pari and Arya are playing a game called Remainders.
Pari chooses two positive integer x and k, and tells Arya k but not x. Arya have to find the value . There are n ancient numbers c1, c2, ..., cn and Pari has to tell Arya if Arya wants. Given k and the ancient values, tell us if Arya has a winning strategy independent of value of x or not. Formally, is it true that Arya can understand the value for any positive integer x?
Note, that means the remainder of x after dividing it by y.
输入
The first line of the input contains two integers n and k (1 ≤ n, k ≤ 1 000 000) — the number of ancient integers and value k that is chosen by Pari.
The second line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 1 000 000).
输出
Print "Yes" (without quotes) if Arya has a winning strategy independent of value of x, or "No" (without quotes) otherwise.
样例
input
4 5
2 3 5 12
output
Yes
input
2 7
2 3
output
No
题意
给你n个数和一个k,求x%k的值,没有告诉你x是多少,只告诉你能够计算x%ci的值。问能不能根据这n次测试唯一确定x%k。
题解
思路1:
结论:无法唯一确定x%k <==> k不能整除lcm(c1,...,cn);
充分性:
无法唯一确定x%k --> 存在两个数x1,x2对于任意的ci取余的值都相等,对k取值的值却不等。
- x1,x2对任意的ci取余都相等 --> ci|(x1-x2) --> lcm(ci)|(x1-x2).
- x1,x2对k取余的值不等 --> k不整除(x1-x2) --> k不整除lcm(ci)
必要性:
我们令x1=2*lcm(ci),x2=lcm(ci),则易知有x1,x2对于任意的ci取余的值都相等,且因为k不能整除lcm(ci),所以x1,x2对k取余的值不等。 所以ci不能确定x%k的值。
思路2:
题目已经给我们n个线性同余方程:x%c[i]==a[i]%c[i]。
由于a数组是由我们任意选择的,所以我们可以构造所有的a相等,从而使得对于任意的i,j,有a[i]%(gcd(ci,cj))等于a[j]%(gcd(ci,cj))。这样,由中国剩余定理就可以知道x%(lcm(c1,...,cn))有唯一解了。 那么我们只要使得k能整除lcm(c1,...,cn)那么易知x%k的值也是固定的。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef __int64 LL;
LL n, k;
LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a%b); }
LL lcm(LL a, LL b) { return a*b / gcd(a, b); }
int main() {
scanf("%I64d%I64d", &n, &k);
LL lcm_ci = 1;
bool su = 0;
for (int i = 1; i <= n; i++) {
LL x;
scanf("%I64d", &x);
lcm_ci = lcm(lcm_ci, x);
lcm_ci = gcd(k, lcm_ci);
if (lcm_ci == k) {
su = 1; break;
}
}
if (su) puts("Yes");
else puts("No");
return 0;
}