题目描述
已知多项式方程:
a0 + a1 x + a2 x2 + ...... + an xn = 0
求这个方程在[1, m]内的整数解(n 和 m 均为正整数)。
输入
输入共 n+2 行。
第一行包含 2 个整数 n、m,每两个整数之间用一个空格隔开。
接下来的 n+1 行每行包含一个整数,依次为 a0,a1,a2,...,an。
输出
第一行输出方程在[1, m]内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。
样例输入
2 10
1
-2
1
样例输出
1
1
题解
做这道题首先要了解秦九韶算法: 秦九韶(约公元1202年-1261年),字道古,南宋末年人,出生于鲁郡
一般地,一元n次多项式的求值需要经过(n+1)*n/2次乘法和n次加法,而秦九韶算法只需要n次乘法和n次加法。在人工计算时,一次大大简化了运算过程。
附上百科的一张图:
于是我们可以在O(nm)的时间内解决这个问题。
等等,高精度怎么办?
当遇到读入的数很大的题时,就要想到mod一个数。------某dalao
对于一个x和模数p,我们设x=kp+b,则x≡b(mod p),同时f(x)≡f(b)(mod p)。因此,我们得出如下结论: 在模p的情况下,f(x)=0的充分必要条件是f(x mod p)=0。
显然,如果f(x mod p)=0,f(x)不一定等于0。那怎么办?我们可以选一个比较优秀的质数,如1e9+7,或者我们可以多选几个质数来保证正确性,这里选择前者。
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=100+50; const int P=1e9+7; ll n,m,t; ll a[maxn],v[maxn],ans[maxn]; ll read(){ char ch;ll fh=1;scanf("%c",&ch); while(ch<'0'||ch>'9'){if (ch=='-') fh=-1;scanf("%c",&ch);} ll num=0; while(ch>='0'&&ch<='9'){num=num*10+ch-'0';num%=P;scanf("%c",&ch);} num*=fh;return num; } int main(){ cin>>n>>m; for(int i=0;i<=n;i++) a[i]=read(); for(int i=1;i<=m;i++){ ll Ans=0; for(int j=n;j>=1;j--){ Ans=((Ans+a[j])*i)%P; } if((Ans+a[0])%P==0) ans[++t]=i; } cout<<t<<endl; for(int i=1;i<=t;i++) cout<<ans[i]<<endl; return 0; }