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]);

}