BZOJ-3751[NOIP2014]解方程(秦久韶演算法+hash)
阿新 • • 發佈:2020-12-06
題目描述
已知多項式方程:
\[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0 \]求這個方程在 \([1,m]\) 內的整數解(\(0<n\leq 100,|a_i|\leq 10^{10000},a_n\neq 0,m<10^6\))。
分析
根據秦九韶演算法:
\[\begin{aligned}&A(x)\\=&a_nx^n+a_{n-1}x^{n-1}+\cdots+a_1x+a_0\\ =&(a_nx^{n-1}+a_{n-1}x^{n-2}+\cdots+a_2x+a_1)x+a_0\\ =&((a_nx^{n-2}+a_{n-3}x^{n-2}+\cdots+a_3x+a_2)x+a_1)x+a_0\\ =&(\cdots((a_nx+a_{n-1})x+a_{n-2})x+\cdots+a_1)x+a_0 \end{aligned} \]由內向外逐層計算一次多項式的值。
\(a_i\) 非常大,將其對一個大質數取模(比如 \(998244353\)),由於 \(A(x)=0\),則 \(A(x)\equiv 0\pmod {p}\),所以取模後用秦久韶演算法再檢驗是正確的(為了防止雜湊衝突可以多選幾個模數)。
程式碼
#include<bits/stdc++.h> using namespace std; const int mod=998244353; inline long long read() { long long x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)){x=(x*10%mod+ch-48)%mod;ch=getchar();} return x*f; } long long n,m,cnt; long long a[1000010],ans[1000010]; bool check(long long x) { long long ans=0; for(int i=n;i>=1;i--) ans=(ans+a[i])*x%mod; ans=(ans+a[0])%mod; if(ans==0) return true; return false; } int main() { bool flag=false; n=read();m=read(); for(int i=0;i<=n;i++) a[i]=read(); for(int i=1;i<=m;i++) { if(check(i)) { ans[++cnt]=i; flag=true; } } if(!flag) { puts("0"); return 0; } cout<<cnt<<endl; for(int i=1;i<=cnt;i++) printf("%lld\n",ans[i]); return 0; }