【noip2014】解方程

题目描述

已知多项式方程:

a0+a1x+a2x^2+..+anx^n=0

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

输入输出格式

输入格式:
输入文件名为equation .in。

输入共n + 2 行。

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

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

输出格式:
输出文件名为equation .out 。

第一行输出方程在[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%的数据: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<10000

对于100%的数据:0< n<=100,|ai|<=10^10000,an!=0,m<1000000

一道思路清奇的题,用什么秦九韶算法
【noip2014】解方程_第1张图片

该算法看似简单,其最大的意义在于将求n次多项式的值转化为求n个一次多项式的值。在人工计算时,利用秦九韶算法和其中的系数表可以大幅简化运算;对于计算机程序算法而言,加法比乘法的计算效率要高很多,因此该算法仍有极大的意义,对于计算机来说,做一次乘法运算所用的时间比作一次加法运算要长得多,所以此算法极大地缩短了CPU运算时间。

明白这个原理,就简单多了假设a0~a5,那么这个式子就可以写成((((((a5*x+a4)*x)+a3)*x+a2)*x)+a1)*x)+a0显然,若x是解,那么式子==0

刚开始没有看到|ai|<=10^10000!(在快读的时候%cansult就好了) 又得请Cansult帮忙。%%%Cansult https://cansult.github.io/
code:

#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
const int mod=1000000007;
ll n,m,a[100001],ans[1000001];
ll tot;

ll read()
{
    ll now=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9')
    {
        now=(now<<1)+(now<<3)+ch-'0';
        now%=mod;
        ch=getchar();
    }
    return now*f;
}

ll judge(ll x)
{
    ll as=0;
    for (ll i=n; i>=0; i--)
    {
        as=as*x+a[i]; as%=mod;
    }
    return as;
}

int main()
{
    n=read(); m=read();
// scanf("%lld%lld",&n,&m);
    for (ll i=0; i<=n; i++) a[i]=read();
    for (ll i=1; i<=m; i++)
        if (judge(i)==0)
        {
            ans[++tot]=i;
        }
    printf("%lld\n",tot);
    for (ll i=1; i<=tot; i++)
        printf("%lld\n",ans[i]); 
    return 0;
}

你可能感兴趣的:(noip真题,巧妙的思路,数学相关)