已知多项式方程:
a0+a1*x^1+a2*x^2+a3*x^3+.........+an*x^n
求这个方程在 [1,m] 内的整数解(n和 m 均为正整数)
输入格式:
共 n + 2 行。
第一行包含 2 个整数 n, m,每两个整数之间用一个空格隔开。
接下来的 n+1行每行包含一个整数,依次为 a0,a1,a2,a3,..... a4
输出格式:
第一行输出方程在 [1,m] 内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在 [1,m] 内的一个整数解。
2 10
1
-2
1
输出:
1
1
输入样例#2:
2 10
2
-3
1
输出:
2
1
2
输入样例#3:
2 10
1
3
2
输出:
0
对于 30% 的数据:0<n<=2,|ai|<=100,an≠0,m<100
对于 50% 的数据:0<n<=100,|ai|<=10^{100},an≠0,m<100
对于 70% 的数据:0<n<=100,|ai|<=10^10000,an≠0,m<10^4
对于 100% 的数据:0<n<=100,|ai|<=10^10000,an≠0,m<10^6
分析:
此题考查的是数论的知识数论什么的根本不会,在%你赛中遇到此题当场去世,结果我写个暴力骗了30分,那么正解呢?
不知道大家有没有听说过秦九韶算法(霍纳定理),秦九韶算法就是将多项式求值简化的一个算法,明确的这道题我们可以考虑这样的做法因为这道题卡的就是代码的复杂度.
秦九韶算法:
此篇博客不证明此算法,如有需求百度问度娘吧,复杂度一般的多项式求值需要经过(n+1)*n/2的乘法和n次加法十分明显的这个复杂度是十分大的,
那秦九韶算法的复杂度呢?
这是一个十分优秀的算法它的复杂度仅仅只需n次乘法和n次加法再看看数据大小加上快读这题就能过了,但是再看数据这么大的数据这肯定是要么用高精度要么疯狂取模啊
在快读里每次模值就可以避免这个问题了
步骤
1.一个循环枚举区间[1~ m]每一种情况跑一遍秦九韶算法.
2.输入时我们用快读边输入边取模.
代码:
#include <iostream> #include <iomanip> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <cstdio> using namespace std; typedef long long LL; const int N=1e6+200; const int mod=1000000007;//注意mod值尽量去一个较大的质数 bool judge; LL a[N],n,m,sum,ans[N],keay; LL calc(LL x) { sum=0; for(LL i=n;i>=1;i--) { sum=(a[i]+sum)*x%mod; } return (sum+a[0])%mod; } LL read() { LL 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‘)%mod; c=getchar(); } return sum*fg; } int main() { n=read(); m=read(); for(LL i=0;i<=n;i++) a[i]=read(); for(LL i=1;i<=m;i++) { ans[i]=calc(i); if(ans[i]%mod==0) { judge=true; keay++; } } if(!judge)//如果没有满足情况的值 { cout<<0<<endl; return 0; } else { cout<<keay<<endl; for(LL i=1;i<=m;i++) { if(ans[i]==0) cout<<i<<endl; } } return 0; }
原文:https://www.cnblogs.com/CCCPKeay/p/9915661.html