题目:http://www.luogu.org/problem/show?pid=2312
分析:
我们很容易就会发现f(x+p) mod p=f(x) mod p
于是我们选择一个小一些的p,预处理出0~p-1所有的f(x),然后超过p的取模即可
但是p不够大会挂啊!
于是我们多选择几个p 分别取一遍mod 只有一个值对所有的p取模之后全都0才算作解
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int Tmax=105;
int n,m,prime[5]={10007,13331,19997,11261,21893},ans[Tmax];
long long int data[Tmax][5],f[21895][5];
char s[Tmax];
void print()
{
printf("%d\n",ans[0]);
for(int i=1;i<=ans[0];i++)
printf("%d\n",ans[i]);
return;
}
void work()
{
int i,j,k,tmp;
bool ok;
for(i=0;i<5;i++) //秦九韶算法
{
for(j=1;j<prime[i];j++)
{
tmp=0;
for(k=n;k>=0;k--)
tmp=(tmp*j+data[k][i])%prime[i];
f[j][i]=tmp;
}
}
for(i=1;i<=m;i++) //检查解
{
ok=true;
for(j=0;j<5;j++)
if(f[i%prime[j]][j]){
ok=false;
break;
}
if(ok) ans[++ans[0]]=i;
}
return;
}
void init()
{
int i,j,k,len;
bool flag;
for(i=0;i<=n;i++)
{
flag=false;
scanf("%s",s+1);
j=1;
if(s[1]=='-'){
flag=true;
j++;
}
len=strlen(s+1);
for(;j<=len;j++)
for(k=0;k<5;k++)
data[i][k]=((data[i][k]<<1)+(data[i][k]<<3)+s[j]-'0')%prime[k];//data[i][k]=(data[i][k]*10+s[j]-'0')%p=(data[i][j]*(8+2)+..)%p=(data[i][k]<<1+data[i][k]<<3+..)%p;
if(flag) for(k=0;k<5;k++) data[i][k]=-data[i][k];
}
return;
}
int main()
{
scanf("%d %d",&n,&m);
init();
work();
print();
return 0;
}