分析:
利用哈希的思想可以避免使用高精度。
枚举可能解时只需枚举到模数-1。
代码:
ZZ代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
typedef long long LL;
const LL MOD0=1e9+7;
const LL MOD1=1e8+9;
const LL MOD2=19260817;
int n,m;
int ans[1000005],tot;
LL a[105][3],ret[3];
inline void read(int i){
LL f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){
a[i][0]=((a[i][0]<<3)+(a[i][0]<<1)+ch-'0')%MOD0;
a[i][1]=((a[i][1]<<3)+(a[i][1]<<1)+ch-'0')%MOD1;
a[i][2]=((a[i][2]<<3)+(a[i][2]<<1)+ch-'0')%MOD2;
ch=getchar();
}
if(f==-1){
a[i][0]=(MOD0-a[i][0])%MOD0;
a[i][1]=(MOD1-a[i][1])%MOD1;
a[i][2]=(MOD2-a[i][2])%MOD2;
}
}
void solve(int x,int pos){
if(!pos) return;
ret[0]=(ret[0]*x+a[pos-1][0])%MOD0;
ret[1]=(ret[1]*x+a[pos-1][1])%MOD1;
ret[2]=(ret[2]*x+a[pos-1][2])%MOD2;
solve(x,pos-1);
}
bool check(int x){
ret[0]=a[n][0];
ret[1]=a[n][1];
ret[2]=a[n][2];
solve(x,n);
return ret[0]==ret[1]&&ret[1]==ret[2]&&ret[2]==0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) read(i);
for(int i=1;i<=m;i++)
if(check(i)) ans[++tot]=i;
printf("%d\n",tot);
for(int i=1;i<=tot;i++)
printf("%d\n",ans[i]);
return 0;
}
AC代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
int n,m,a[105][6];
int prm[6]={0,24001,24007,24019,24023,24029};
int tag[1000005];
inline void read(int id){
int f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){
for(int i=1;i<=5;i++)
a[id][i]=((a[id][i]<<3)+(a[id][i]<<1)+ch-'0')%prm[i];
ch=getchar();
}
if(f==-1){
for(int i=1;i<=5;i++)
a[id][i]=(prm[i]-a[id][i])%prm[i];
}
}
int main(){
scanf("%d%d",&n,&m);int ans=0;
for(int i=0;i<=n;i++) read(i);
for(int i=1;i<=5;i++){
for(int j=0;j<prm[i];j++){
int temp=a[n][i];
for(int k=n-1;k+1;k--)
temp=(temp*j+a[k][i])%prm[i];
if(temp==0){
for(int k=j;k<=m;k+=prm[i]){
tag[k]++;
if(tag[k]==5) ans++;
}
}
}
}
printf("%d\n",ans);
for(int i=1;i<=m;i++)
if(tag[i]==5) printf("%d\n",i);
return 0;
}