您的位置:首页 > 其它

Codeforces 338D GCD Table [中国剩余定理]

2018-03-20 22:07 295 查看
Description:

给一个n∗mn∗m的数表,第ii行jj列的元素是gcd(i,j)gcd(i,j)。再给出一行数,问这行数是否出现在数表中。

Solution:

根据结论,我们知道行数是lcm(a1,...,ak)lcm(a1,...,ak),然后我们列出方程,用crtcrt合并,这样可以解出列数。

代码抄了一份,并没有搞懂crtcrt,留坑。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, m, L = 1, x, lcm, ans;
int k;
ll a[100005];
ll mul(ll x, ll y, ll P) {
ll ret = 0;
for(y = (y % P + P) % P; y; y >>= 1, x = (x + x) % P) {
if(y & 1) {
ret = (ret + x) % P;
}
}
return ret;
}
ll exgcd(ll a, ll b, ll &x, ll &y) {
if(!b) {
x = 1;
y = 0;
return a;
}
ll ret = exgcd(b, a % b, y, x);
y -= (a / b) * x;
return ret;
}
int main() {
scanf("%lld%lld%d", &n, &m, &k);
for(int i = 1; i <= k; ++i) {
scanf("%lld", &a[i]);
lcm = lcm / __gcd(a[i], lcm) * a[i];
ll x, y, d = exgcd(L, a[i], x, y);
if((ans + (i - 1) % a[i]) % d != 0 || L / d * a[i] > n) {
return puts("NO"), 0;
}
x *= (ans + (i - 1) % a[i]) / d;
ans = ans - mul(L, x, L / d * a[i]);
L = L / d * a[i];
ans = (ans % L + L) % L;
}
if(ans == 0) {
ans = L;
}
if(ans + k - 1 > m) {
return puts("NO"), 0;
}
for(int i = 1; i <= k; ++i) {
if(a[i] != __gcd(L, ans + i - 1)) {
return puts("NO"), 0;
}
}
puts("YES");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: