problem
已知多项式方程:
a 0 + a 1 x + a 2 x 2 + ⋯ + a n x n = 0 a_0+a_1x+a_2x^2+\cdots+a_nx^n=0 a0+a1x+a2x2+⋯+anxn=0
求这个方程在 [ 1 , m ] [1,m] [1,m] 内的整数解( n n n 和 m m m 均为正整数)。
数据范围: 0 < n ≤ 100 0<n\le 100 0<n≤100, ∣ a i ∣ ≤ 1 0 10000 |a_i|\le 10^{10000} ∣ai∣≤1010000, a n ≠ 0 a_n≠0 an=0, m < 1 0 6 m<10^6 m<106。
solution
怎么感觉 14 年的题都挺简单的。。
这道题主要就是两个问题。
1 1 1、 a i a_i ai 过大,怎么处理?
对 a i a_i ai 取模,转换成模意义下的计算。
如果觉得不保险就多对几个数取模,不过对于此题用 1 0 9 + 7 10^9+7 109+7 就够了。
2 2 2、如何比较快速地求一个多项式的值?
这个就直接用秦九昭算法暴力展开就好了,即:
f ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x + a 0 = ( a n x n − 1 + a n − 1 x n − 2 + ⋯ + a 2 x + a 1 ) x + a 0 = ( ( a n x n − 2 + a n − 1 x n − 3 + ⋯ + a 3 x + a 2 ) x + a 1 ) x + a 0 ⋮ = ( ⋯ ( a n x + a n − 1 ) x + ⋯ + a 1 ) x + a 0 \begin{aligned} f(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-1}x^{n-3}+\cdots+a_3x+a_2)x+a_1)x+a_0\\ &\;\;\vdots\\ &=(\cdots(a_nx+a_{n-1})x+\cdots+a_1)x+a_0 \end{aligned} f(x)=anxn+an−1xn−1+⋯+a1x+a0=(anxn−1+an−1xn−2+⋯+a2x+a1)x+a0=((anxn−2+an−1xn−3+⋯+a3x+a2)x+a1)x+a0⋮=(⋯(anx+an−1)x+⋯+a1)x+a0
那么我们就可以在 O ( n ) O(n) O(n) 的时间内计算出一个点 x x x 的 f ( x ) f(x) f(x) 值。
然后直接枚举 ∀ i ∈ [ 1 , m ] \forall i\in[1,m] ∀i∈[1,m],暴力验证即可。
时间复杂度 O ( n m ) O(nm) O(nm),但是常数小能过。
code
#include<bits/stdc++.h>
#define P 1000000007
using namespace std;
int add(int x,int y) {return x+y>=P?x+y-P:x+y;}
int dec(int x,int y) {return x-y< 0?x-y+P:x-y;}
int mul(int x,int y) {return 1ll*x*y%P;}
namespace IO{
const int Rlen=1<<22|1;
char buf[Rlen],*p1,*p2;
inline char gc(){
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T Read(){
T x=0,f=1;char c=gc();
while(!isdigit(c)&&c!='-') c=gc();
if(c=='-') f=0,c=gc();
while(isdigit(c)) x=add(mul(10,x),c^48),c=gc();
return f?x:(P-x);
}
inline int in() {return Read<int>();}
inline void out(int x){
if(x>9) out(x/10);
putchar(x%10+'0');
}
}
using IO::in;
using IO::out;
int n,m,tot,a[105],ans[1000005];
int calc(int x){
int val=0;
for(int i=n;i>=1;--i) val=mul(add(a[i],val),x);
return add(val,a[0]);
}
int main(){
n=in(),m=in();
for(int i=0;i<=n;++i) a[i]=in();
for(int i=1;i<=m;++i) if(!calc(i)) ans[++tot]=i;
out(tot),putchar('\n');
for(int i=1;i<=tot;++i) out(ans[i]),putchar('\n');
return 0;
}