「NOIP 2014」解方程-Hash

分析

令$f(x) = a_0 + a_1 x + a_2x^2 + \cdot \cdot \cdot + a_nx^n = 0$,那么对于一个质数$p$取模,如果有$f(x) = 0$,则一定有$f(x)% p = 0$。
我们只需要求出所有满足$f(x)%p = 0$的$x$,然后模另一个质数检验。
时间复杂度为$O(np + n \frac{nm}{p})$。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <bits/stdc++.h>
using namespace std;
char ch;
inline void read(int &x) {
x = 0;
do ch = getchar(); while (!isdigit(ch));
while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ '0'), ch = getchar();
}
const int MAXN = 100;
const int MAXLEN = 10000 + 1;
const int MAXM = 1000000;
const int MOD1 = 21893;
const int MOD2 = 18341629;
inline int parse(const char *s, const int mod) {
int res = 0, sgn = 1;
if (*s == '-') s++, sgn = -1;
for (const char *p = s; *p; p++) res = ((res << 1) + (res << 3) + (*p ^ '0')) % mod;
return res * sgn;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
static char s[MAXN + 1][MAXLEN + 1];
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i <= n; i++)
scanf("%s", s[i]);
static int a[MAXN + 1];
for (int i = 0; i <= n; i++) a[i] = parse(s[i], MOD1);
std::list<int> roots;
for (int i = 1; i < MOD1; i++) {
long long pow = 1, val = 0;
for (int j = 0; j <= n; j++) {
(val += a[j] * pow) %= MOD1;
pow = pow * i % MOD1;
}
if (val == 0) {
for (int j = i; j <= m; j += MOD1) roots.push_back(j);
}
}
for (int j = 0; j <= n; j++) a[j] = parse(s[j], MOD2);
for (std::list<int>::iterator it = roots.begin(); it != roots.end(); ) {
long long pow = 1, val = 0;
for (int j = 0; j <= n; j++) {
(val += a[j] * pow) %= MOD2;
pow = pow * *it % MOD2;
}
if (val != 0) it = roots.erase(it);
else it++;
}
cout << roots.size() << "\n";
roots.sort();
for (std::list<int>::iterator it = roots.begin(); it != roots.end(); it++)
cout << *it << "\n";
return 0;
}
#

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×