听别人说是noip很有趣的一题。
题面
我一开始看成N,M都很大,以为是用NTT搞快速插值之类的,就自然想到取模。模1004535809为0,大概多项式就是0了。
再仔细看数据范围,发现可以暴力搞,大概选几个四位(质)数作为模数,枚举1~10000,分别在同余的情况下算出结果。
然后枚举1~m,看是否同余都为0即可。
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define mmst(a, b) memset(a, b, sizeof(a))
#define mmcp(a, b) memcpy(a, b, sizeof(b))
typedef long long LL;
const int N=100100;
const int M[6]={2233,2333,6666,9949,9967,9973};
int num,n,m,a[6][N];
bool ok[6][N];
char cc[N];
bool judge(int x)
{
for(int j=0;j<6;j++)
if(!ok[j][x%M[j]])
return false;
return true;
}
int main()
{
cin>>n>>m;
for(int i=0;i<=n;i++)
{
scanf("%s",cc);
int len=strlen(cc);
for(int j=0;j<6;j++)
{
int k=0,tu=1;
if(cc[0]=='-')
k=1,tu=-1;
for(;k<len;k++)
a[j][i]=((a[j][i]<<3)+(a[j][i]<<1)+cc[k]-'0')%M[j];
a[j][i]=(a[j][i]*tu+M[j])%M[j];
}
}
for(int j=0;j<6;j++)
ok[j][0]=1;
for(int i=1;i<=10000;i++)
for(int j=0;j<6;j++)
{
int v=1,sum=0;
for(int k=0;k<=n;k++)
sum=(sum+a[j][k]*v)%M[j],v=v*i%M[j];
if(!sum)
ok[j][i]=1;
}
for(int i=1;i<=m;i++)
if(judge(i))
num++;
cout<<num<<endl;
for(int i=1;i<=m;i++)
if(judge(i))
printf("%d\n",i);
return 0;
}