【noip2014】解方程

题目描述

已知多项式方程:

                               a0 + a1 x + a2 x2 + ...... + an xn = 0

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


输入

输入共 n+2 行。

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

接下来的 n+1 行每行包含一个整数,依次为 a0,a1,a2,...,an


输出

第一行输出方程在[1, m]内的整数解的个数。

接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。


样例输入

2 10
1
-2
1


样例输出

1
1


题解

做这道题首先要了解秦九韶算法:  秦九韶(约公元1202年-1261年),字道古,南宋末年人,出生于鲁郡

一般地,一元n次多项式的求值需要经过(n+1)*n/2次乘法和n次加法,而秦九韶算法只需要n次乘法和n次加法。在人工计算时,一次大大简化了运算过程。

附上百科的一张图:

于是我们可以在O(nm)的时间内解决这个问题。

等等,高精度怎么办?

           当遇到读入的数很大的题时,就要想到mod一个数。------某dalao

对于一个x和模数p,我们设x=kp+b,则x≡b(mod p),同时f(x)≡f(b)(mod p)。因此,我们得出如下结论: 在模p的情况下,f(x)=0的充分必要条件是f(x mod p)=0。 

显然,如果f(x mod p)=0,f(x)不一定等于0。那怎么办?我们可以选一个比较优秀的质数,如1e9+7,或者我们可以多选几个质数来保证正确性,这里选择前者。

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long

const int maxn=100+50;
const int P=1e9+7;

ll n,m,t;
ll a[maxn],v[maxn],ans[maxn];

ll read(){
    char ch;ll fh=1;scanf("%c",&ch);
    while(ch<'0'||ch>'9'){if (ch=='-') fh=-1;scanf("%c",&ch);}
    ll num=0;
    while(ch>='0'&&ch<='9'){num=num*10+ch-'0';num%=P;scanf("%c",&ch);}
    num*=fh;return num;
}

int main(){
    cin>>n>>m;
    for(int i=0;i<=n;i++) a[i]=read();
    for(int i=1;i<=m;i++){
        ll Ans=0;
        for(int j=n;j>=1;j--){
            Ans=((Ans+a[j])*i)%P;
        }
        if((Ans+a[0])%P==0) ans[++t]=i;
    }
    cout<<t<<endl;
    for(int i=1;i<=t;i++) cout<<ans[i]<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/rlddd/p/9515590.html