题目描述 Description
输入描述 Input Description
输入文件名为equation.in。
输入共n+2行。
第一行包含2个整数n、m,每两个整数之间用一个空格隔开。
接下来的n+1行每行包含一个整数,依次为a0,a1,a2,……,an。
输出描述 Output Description
输出文件名为equation.out。
第一行输出方程在[1, m]内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。
样例输入 Sample Input
equation.in |
equation.out |
2 10 1 -2 1
|
1 1 |
equation.in |
equation.out |
2 10 2 -3 1
|
2 1 2 |
样例输出 Sample Output
equation.in |
equation.out |
2 10 1 3 2
|
0 |
数据范围及提示 Data Size & Hint
http://codevs.cn/problem/3732/
30% 我们只需要枚举1到m并且计算f(i)是否为0即可
50% 与30%思路相同,只是改为高精度(建议使用重载运算符)
70% 取5,6个较大的模数,将ai输入的同时进行取模,如果都为0就记为答案
100% 对于f(i)的值取模p时,f(i)=f(i%p)所以不需要枚举到m,只要到每个质数-1,即可,而较大的数的值只需找对应的5个值查看即可。
#include<cstdio> #include<cstring> int n,pr[5]={11261,19997,22877,21893,14843},qm[105][5],jl[1000005]; bool vis[5][30005]; char c[10005]; int f(int a,int b,int c) { if(a==n) return qm[n][b]; return (qm[a][b]+f(a+1,b,c)*c%pr[b])%pr[b]; } int main() { int m,ans=0; scanf("%d%d",&n,&m); for(int i=0;i<=n;++i) { scanf("%s",c); int l=strlen(c),f=c[0]=='-'?1:0; for(int j=0;j<5;++j) { for(int k=f;k<l;++k) qm[i][j]=(qm[i][j]*10+c[k]-'0')%pr[j]; if(f) qm[i][j]=-qm[i][j]; } } for(int i=0;i<5;++i) for(int j=0;j<pr[i];++j) if(f(0,i,j)) vis[i][j]=1; for(int i=1;i<=m;++i) { bool sf=1; for(int j=0;j<5;++j) if(vis[j][i%pr[j]]) sf=0; if(sf) jl[ans++]=i; } printf("%d\n",ans); for(int i=0;i<ans;++i) printf("%d\n",jl[i]); return 0; }