题面
题解
这题十分玄学,貌似想破头都只有50分的暴力。
什么牛顿迭代法、FFT各种牛B算法好像都不行,高精度只有暴力分。
正解基于以下
n=0=>n%p=0
逆命题明显不对,但是多搞几个质数做
p
,都有
然后多项式
于是我们就弄五个质数,每个质数要很适合AC,是什么样请参考代码。然后预处理出个表,
f[i][j]
代表第
i
个质数做
时间就是 O(n∗cnt∗pi+m∗cnt) , cnt 是选的质数的数量, pi 则是它们的大小。
神奇的代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n, m, a[5][105], f[5][20050], ans[105];
const int prime[] = {20011, 20021, 20023, 20029, 20047};
const int cnt = 5;
void Read(int x){
bool f = true;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = false; ch = getchar();}
int ret[5];
for(int i = 0; i < cnt; i++) ret[i] = 0;
while(ch >= '0' && ch <= '9'){
for(int i = 0; i < cnt; i++)
ret[i] = ((ret[i] << 3) + (ret[i] << 1) + ch - '0') % prime[i];
ch = getchar();
}
for(int i = 0; i < cnt; i++)
a[i][x] = f ? ret[i] : prime[i] - ret[i];
}
int calc(int t, int x){
int ret = 0;
for(int i = n; i >= 0; i--)
ret = (ret * x + a[t][i]) % prime[t];
return ret;
}
int main(){
freopen("lgP2312.in", "r", stdin);
freopen("lgP2312.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; i++) Read(i);
for(int i = 0; i < cnt; i++)
for(int j = 0; j < prime[i]; j++)
f[i][j] = calc(i, j);
for(int i = 1; i <= m; i++){
bool ok = true;
for(int j = 0; j < cnt; j++)
if(f[j][i % prime[j]]) ok = false;
if(ok)
ans[++ans[0]] = i;
}
printf("%d\n", ans[0]);
for(int i = 1; i <= ans[0]; i++)
printf("%d\n", ans[i]);
return 0;
}
答案是偶然?必然?
你曾经选择的道路,才是真正的命运。
紧握在手心的希望也好、不安也罢,
必定会化作驱使我们前进的光。