洛谷 P2312 解方程 题解

P2312 解方程

题目描述

已知多项式方程:

[a_0+a_1x+a_2x^2+cdots+a_nx^n=0 ]

求这个方程在 [1,m][1,m] 内的整数解((n)(m) 均为正整数)。

输入格式

输入共 $ n + 2$ 行。

第一行包含 (2) 个整数 (n, m) ,每两个整数之间用一个空格隔开。

接下来的 (n+1) 行每行包含一个整数,依次为 (a_0,a_1,a_2ldots a_n)

输出格式

第一行输出方程在 [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

说明/提示

对于 30%30% 的数据:(0<nle 2,|a_i|le 100,a_n≠0,m<100)

对于 50%50% 的数据:(0<nle 100,|a_i|le 10^{100},a_n≠0,m<100)

对于 70%70% 的数据:(0<nle 100,|a_i|le 10^{10000},a_n≠0,m<10^4)

对于 100%100% 的数据:(0<nle 100,|a_i|le 10^{10000},a_n≠0,m<10^6)

【思路】

秦九韶公式 + 快读取模 +数学、数论

【题目大意】

给定范围求范围内方程解的个数

【题目分析】

m<=1e6,可以枚举
所以枚举m是个不错的选择
方程求解?可以代数试一下
但是代数复杂度太高
可以用秦九韶公式分解一下
不会的话可看后面的解释或者百度一下,记住公式就好了挺简单的
降低复杂度

【核心思路】

枚举m
然后去判断一下m是不是方程的解
只需要将m带入方程试一下
注意:
这里的方程式秦九韶公式分解之后的方程
然后计数记录答案最后输出就好了

【秦九韶公式】

(a_0 + a_1x + a_2x^2 + a_3x^3 + .... + a_nx^n)
(=a_0 + x(a_1+a_2x+a_3x^2+....+a_nx^{n-1}))
(=....)
就是上面这个样子
可以化到里面没有几次方
未知数都是多少的1次方的情况
这样就可以减少很多的运算量

【完整代码】

#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
const int p = 1e9 + 7;
inline int read()
{
	int sum = 0,fg = 1;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-')fg = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		sum = ((sum * 10) + c - '0') % p;
		c = getchar();
	}
	return sum * fg;
}
int a[105];
int ans[1000006];
int n,m;
bool check(int x)
{
	int sum = 0;
	for(register int i = n;i >= 1;i --)
	{
		sum = (x * (a[i] + sum)) % p ;
	}
	sum = (sum + a[0]) % p;
	if(sum == 0)return true;
	else	return false;
}

signed main()
{
	freopen("au.out","r",stdin);
	n = read();m = read();
	for(register int i = 0;i <= n;++ i)
		a[i] = read();
	int js = 0;
	for(register int i = 1;i <= m;++ i)
		if(check(i) == true)
			ans[++ js] = i;
	cout << js << endl;
	for(register int i = 1;i <= js;++ i)
		cout << ans[i] << endl;
	return 0; 
}
原文地址:https://www.cnblogs.com/acioi/p/11725908.html