[NOIP2014] 解方程 题解

题目传送门
题目描述
已知多项式方程:
a 0 + a 1 ∗ x + a 2 ∗ x 2 + ⋯ + a n ∗ x n = 0 a0+a1*x+a2*x^2+\dots+an*x^n=0 a0+a1x+a2x2++anxn=0
求这个方程在 [ 1 , m ] [1,m] [1,m] 内的整数解( n n n m m m 均为正整数)。
输入格式
输入共 n + 2 n + 2 n+2 行。
第一行包含 2 2 2 个整数 n , m n, m n,m,每两个整数之间用一个空格隔开。
接下来的 n+1n+1 行每行包含一个整数,依次为 a 0 , a 1 , a 2 … a n a0,a1,a2\dots an a0,a1,a2an
输出格式
第一行输出方程在 [ 1 , m ] [1,m] [1,m] 内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在 [ 1 , m ] [1,m] [1,m] 内的一个整数解。
输入输出样例
输入 #1

2 10 
1
-2
1

输出 #1

1
1

输入 #2

2 10
2
-3
1

输出 #2

2
1
2

输入 #3

2 10
1
3
2

输出 #3

0

说明/提示
在这里插入图片描述
题目解析
秦九韶算法结论:对于一个n次多项式,至多做n次乘法和n次加法。
不会秦九韶算法?点这里
不难发现,我们只要枚举区间 [ 1 , m ] [1,m] [1,m] 之间的整数,带入多项式, Θ ( n ) \Theta(n) Θ(n) 求出多项式的值,如果与 0 0 0 相等就算一个整数解。算法复杂度 Θ ( n m ) \Theta(nm) Θ(nm)
但是我们看: ∣ a i ∣ ≤ 1 0 10000 |a_i|\le10^{10000} ai1010000 显然不能直接算,我们只需要模一个大质数就可以了,但是不能有数被整除,这样就不会爆int了,经过检验, 222222227 222222227 222222227 (8个2,1个7)就是一个很好的大质数。
代码:

#include<cstdio>
#define maxn 1039
#define MOD 222222227//8217 
using namespace std;
typedef long long ll;
typedef long long Type;
inline Type read(){
    
    
	Type sum=0;
	int flag=0;
	char c=getchar();
	while((c<'0'||c>'9')&&c!='-') c=getchar();
	if(c=='-') c=getchar(),flag=1;
	while('0'<=c&&c<='9'){
    
    
		sum=(sum<<1)+(sum<<3)+(c^48);
		sum%=MOD;
		c=getchar();
	}
	if(flag) return -sum;
	return sum;
}
int n,m;
ll a[maxn],ans[maxn];
int cnt;
int check(int x){
    
    
	ll res=1;
	ll ans=0;
	for(int i=0;i<=n;i++){
    
    
		ans+=res*a[i];
		ans%=MOD;
		res=res*x%MOD;
	}
	if(ans%MOD==0) return 1;
	return 0;
}
int main(){
    
    
	scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++)
        a[i]=read();
    int cnt=0;
    for(int i=1;i<=m;i++)
        if(check(i)){
    
    
        	ans[++cnt]=i;
		}
	printf("%d\n",cnt);
	for(int i=1;i<=cnt;i++)
	    printf("%d\n",ans[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jiangtaizhe/article/details/108951801
今日推荐