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_2\ldots 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<n\le 2,|a_i|\le 100,a_n≠0,m<100\)。
对于 50%50% 的数据:\(0<n\le 100,|a_i|\le 10^{100},a_n≠0,m<100\) 。
对于 70%70% 的数据:\(0<n\le 100,|a_i|\le 10^{10000},a_n≠0,m<10^4\) 。
对于 100%100% 的数据:\(0<n\le 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; }