BZOJ里的第二道noip题,今年防ak题,OTZ。
最初直接用大素数取模的方法要TLE,虽然本机不会。
用几个小质数pni,算出在模pni的同余系里0~pni-1的答案。如果x为原方程的解的话x%pni在模pni意义下也应该为0。
然后还是会TLE,最后发现小质数乘的时候不用取模了。bzoj上这题纯粹是丧心病狂卡常数啊。
ORZMHY
#define PROC "equation"
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long uqw;
typedef long long qw;
const int maxn = 109;
const int maxl = 10009;
const int maxm = 1000009;
const int cp = 5;
//const int pn[cp] = {111119, 23333, 11113, 23251, 33329};
const int pn[] = {22861, 22871, 22877, 22901, 22907, 22921};
const int p10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
struct bigInt {
int v[3009], l, nag;
bigInt() {
l = 0;
}
void init(char* a) {
char *i = a, *j;
if (a[0] == '-')
++ i, nag = 1;
else
nag = 0;
j = i;
while (*j)
++ j;
-- j;
l = 0;
while (j >= i) {
v[l] = 0;
for (int k = 0; k < 8 && j >= i; -- j, ++ k)
v[l] = v[l] + (*j - 48) * p10[k];
++ l;
}
}
int mod(int x) {
int t = 0;
for (int i = l - 1; i >= 0; -- i)
t = ((qw)t * 100000000 + v[i]) % x;
return nag ? ((x - t) % x) : t;
}
};
int n, m, ans[maxm], tans;
int ha[maxn];
int pm[cp][maxm];
char a[maxl];
bigInt a0[maxn];
int calc(int x, int m) {
int s = ha[n];
for (int i = n - 1; i >= 0; -- i)
s = (s * x + ha[i]) % m;
return s;
}
int main() {
#ifndef ONLINE_JUDGE
freopen(PROC ".in", "r", stdin);
freopen(PROC ".out", "w", stdout);
#endif
scanf("%d%d", &n, &m);
for (int i = 0; i <= n; ++ i) {
scanf("%s", a);
a0[i]. init(a);
}
for (int i = 0; i < cp; ++ i) {
for (int j = 0; j <= n; ++ j)
ha[j] = a0[j]. mod(pn[i]);
for (int j = 0; j < pn[i]; ++ j)
pm[i][j] = calc(j, pn[i]);
}
for (int i = 1; i <= m; ++ i) {
bool le = 1;
for (int j = 0; j < cp && le; ++ j)
if (pm[j][i % pn[j]])
le = 0;
if (le)
ans[tans ++] = i;
}
printf("%d\n", tans);
for (int i = 0; i < tans; ++ i)
printf("%d\n", ans[i]);
}