【UOJ #20】【NOIP 2014】解方程

时间:2023-03-09 04:19:13
【UOJ #20】【NOIP 2014】解方程

http://uoj.ac/problem/20

并不会做。。。然后看题解。。。。。。。

对a取模,避免了高精度带来的复杂度,然后再枚举x判断是否满足模意义下等于0。

取5个模数,我直接抄的别人的_(┐「ε:)_。时间复杂度$O(nm)$。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int p[5] = {11261,19997,22877,21893,14843}; char s[10003];
int n, m, a[5][103], cal[5][30003], ans[1000003], anslen = 0; bool pd(int x) {
for(int tmp = 0; tmp < 5; ++tmp)
if (cal[tmp][x % p[tmp]] != 0) return false;
return true;
} int main() {
scanf("%d%d", &n, &m);
int len;
bool fu;
for(int i = 0; i <= n; ++i) {
scanf("%s", s + 1);
len = strlen(s + 1);
fu = false;
for(int tmp = 0; tmp < 5; ++tmp)
if (s[1] == '-') {fu = true; a[tmp][i] = 0;}
else a[tmp][i] = s[1] - '0';
for(int tmp = 0; tmp < 5; ++tmp) {
for(int j = 2; j <= len; ++j)
a[tmp][i] = (a[tmp][i] * 10 + s[j] - '0') % p[tmp];
if (fu) a[tmp][i] = -a[tmp][i];
}
} for(int tmp = 0; tmp < 5; ++tmp) {
for(int x = 1; x <= p[tmp]; ++x) {
int ret = a[tmp][n];
for(int i = n - 1; i >= 0; --i)
ret = (ret * x + a[tmp][i]) % p[tmp];
cal[tmp][x] = ret;
}
} for(int i = 1; i <= m; ++i)
if (pd(i))
ans[++anslen] = i; printf("%d\n", anslen);
for(int i = 1; i <= anslen; ++i)
printf("%d\n", ans[i]);
return 0;
}

_(:з」∠)_【UOJ #20】【NOIP 2014】解方程