Description
已知多项式方程: a0+a1x+a2x^2+...+anx^n=0 求这个方程在[1, m]内的整数解(n 和 m 均为正整数)。
Input Format
输入共 n+2 行。 第一行包含 2 个整数 n、m,每两个整数之间用一个空格隔开。 接下来的 n+1 行每行包含一个整数,依次为a0, a1, a2, ..., an。
Output Format
第一行输出方程在[1, m]内的整数解的个数。 接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。
Sample Input
样例输入1
2 10
1
-2
1
样例输入2
2 10
2
-3
1
样例输入3
2 10
1
3
2
Sample Output
样例输出1
1
1
样例输出2
2
1
2
样例输出3
0
Solution
(毒瘤王f-void用70%的做法+O3优化过了 导致一堆大佬紧跟其后 不打正解 所以……)正解要用到一个性质 因为方程左边等于0 0 mod 任何数都为0
若 x % k=0 那么 (x+nk) %k =0
枚举1-k的数 作为x判断方程左边是否为0
为0则为解
而 k+1 - n的数 只要通过 前面的数+nk就可以得到
比如0+k=k 1+k=k+1; 所以我们只要枚举1 - k-1就行了
k应该选择素数 并且多组
因为可能存在x 使方程左边为k的倍数
这样mod也是0 但并不是方程的解
选择多组保证数据准确
因为a很大 读入应该用字符读 边读边%
计算方程左边的值时,可以用(秦九韶?),
我的写法是((an*x+an-1)*x+an-2)*x……)*x;
若 x % k=0 那么 (x+nk) %k =0
枚举1-k的数 作为x判断方程左边是否为0
为0则为解
而 k+1 - n的数 只要通过 前面的数+nk就可以得到
比如0+k=k 1+k=k+1; 所以我们只要枚举1 - k-1就行了
k应该选择素数 并且多组
因为可能存在x 使方程左边为k的倍数
这样mod也是0 但并不是方程的解
选择多组保证数据准确
因为a很大 读入应该用字符读 边读边%
计算方程左边的值时,可以用(秦九韶?),
我的写法是((an*x+an-1)*x+an-2)*x……)*x;
#include<cstdio> #include<cstring> int n,m; int a[5][105]; int f[5][10005]; int pri[5]= {9931,9941,9949,9967,9973}; int ans[1000005],ansl; int read() { char c=getchar(); int temp=0,f=1; while (c<'0'||'9'<c) { if (c=='-') f=-1; c=getchar(); } while ('0'<=c&&c<='9') { temp=temp*10+c-'0'; c=getchar(); } return temp*f; } bool judge(int i) { for (int t=0; t<5; t++) { if (f[t][i%pri[t]]) return false; } return true; } int main() { n=read(); m=read(); for (int i=0; i<=n; i++) { char ch[10005]; scanf("%s",ch); int len=strlen(ch),z=0; for (int t=0; t<5; t++) { if (ch[0]=='-') a[t][i]=0,z=1; else a[t][i]=ch[0]-'0'; } for (int t=0; t<5; t++) { for (int j=1; j<=len-1; j++) { a[t][i]=(a[t][i]*10+ch[j]-'0')%pri[t]; } if (z==1) a[t][i]=-a[t][i]; } } for (int t=0; t<5; t++) { for (int x=1; x<=pri[t]; x++) //((an*x+an-1)*x+an-2)*x; { int temp=0; for (int i=n; i>=0; i--) { temp=(temp*x+a[t][i])%pri[t]; } f[t][x%pri[t]]=temp; } } for (int i=1; i<=m; i++) { if (judge(i)) { ans[++ansl]=i; } } printf("%d\n",ansl); for (int i=1; i<=ansl; i++) printf("%d\n",ans[i]); }