NOIP2014/洛谷P2312 解方程

NOIP2014/洛谷P2312 解方程

题目描述

已知多项式方程:

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

分析

对于30%的数据,用公式解就可以了。

对于50%的数据,高精度?

对于100%,m的范围不大,在这个范围内枚举,计算最后的值是否为0。要用到秦九韶算法,这样只需要做n次乘法,n次加法。但是a很大,高精度也很难表示怎么办?如果方程左面的值为0,那么方程两边同时mod一个值还是成立的。如果只mod一个值的话,答案很有可能不是正确的,因为如果这个值要是mod这个值的倍数的话,mod的值也是0。我们可以多mod几个值,那么这个数就必须满足是这几个值的最小公倍数的倍数才能在mod之后都为0,否则的话这个数就是0。但是前一种情况机率还是很小的,因为如果模数都取质数的话最小公倍数就是这几个数的乘积,还是很大的。但是这样的话时间复杂度是O(n*m)的,会超时的。如果一个数x mod p !=0 的话,那么x+p mod p!=0,这样就可以少计算一些无用的数。这样的话应该能通过官方数据。

关于秦九韶算法a[0]是否要乘以x,从公式上来看是不需要的,但是如果到最后结果如果是0的话就算乘以x之后还是0,对结果没有什么太大的影响,而且好记,代码短(lazy!)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1000010;
const int mo1=99991;
const int mo2=998244353;
const int mo3=1e9+7;
int n,m,cnt,a[N],b[N],c[N],ans[N]; bool vis[N];
inline void read(int i){
    ll x1=0,x2=0,x3=0,f=1; char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){
        x1=(x1*10+ch-‘0‘)%mo1;
        x2=(x2*10+ch-‘0‘)%mo2;
        x3=(x3*10+ch-‘0‘)%mo3;
        ch=getchar();
    }
    a[i]=x1*f;b[i]=x2*f;c[i]=x3*f;
}
inline bool calc1(int x){
    ll sum=0;
    for(int i=n;i>=0;--i)
        sum=((a[i]+sum)*x)%mo1;
    return !sum;
}
inline bool calc2(int x){
    ll sum1=0,sum2=0;
    for(int i=n;i>=0;--i){
        sum1=((b[i]+sum1)*x)%mo2;
        sum2=((c[i]+sum2)*x)%mo3;
    }
    return (!sum1)&&(!sum2);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;++i) read(i);
    for(int i=1;i<=mo1;++i)
    if(calc1(i)){
        for(int j=i;j<=m;j+=mo1)
        if(calc2(j)) vis[j]=1;
    }
    for(int i=1;i<=m;++i) if(vis[i]) ans[++cnt]=i;
    printf("%d\n",cnt);
    for(int i=1;i<=cnt;++i) printf("%d\n",ans[i]);
    return 0;
}
时间: 2024-10-08 10:08:57

NOIP2014/洛谷P2312 解方程的相关文章

[NOIP2014] 提高组 洛谷P2312 解方程

题目描述 已知多项式方程: 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 ] 内的整数解的个数. 接下来每行一个整数,按照从小到

洛谷 P2312 解方程

题目描述 已知多项式方程: $a_0+a_1x+a_2x^2+..+a_nx^n=0$//用LaTex好看多了 求这个方程在[1, m ] 内的整数解(n 和m 均为正整数) 输入输出格式 输入格式: 输入文件名为equation .in. 输入共n + 2 行. 第一行包含2 个整数n .m ,每两个整数之间用一个空格隔开. 接下来的n+1 行每行包含一个整数,依次为a0,a1,a2..an 输出格式: 输出文件名为equation .out . 第一行输出方程在[1, m ] 内的整数解的个

codevs3732==洛谷 解方程P2312 解方程

P2312 解方程 195通过 1.6K提交 题目提供者该用户不存在 标签数论(数学相关)高精2014NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, m ] 内的整数解(n 和m 均为正整数) 输入输出格式 输入格式: 输入文件名为equation .in. 输入共n + 2 行. 第一行包含2 个整数n .m ,每两个整数之间用一个空格隔开. 接下来的n+1 行每行包含一个整数,依次

[noip2014]P2312 解方程

P2312 解方程 其实这道题就是求一个1元n次方程在区间[1, m]上的整数解. 我们枚举[1, m]上的所有整数,带进多项式中看看结果是不是0即可. 这里有一个技巧就是秦九韶算法,请读者自行查看学习. 时间复杂度O(n*m). 然后你应该可以拿30分. 我们发现这些数都太大了,要开高精度.然后你愉快地拿了50分——复杂度O(n*m*length)会爆炸. 这里我们考虑hash的思想,对结果取模(最好是一个很大的质数P),如果结果是零就说明这是一个解. 应为如果结果是零,那么要么这是一个解,要

luogu P2312 解方程

题目描述 已知多项式方程: 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 ] 内的整数解的个数. 接下来每行一个整数,按照从小到

P2312 解方程

题目描述 已知多项式方程: 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 ] 内的整数解的个数. 接下来每行一个整数,按照从小到

[NOIP2014提高组]解方程

题目:BZOJ3751.洛谷P2312.UOJ#20.Vijos P1910.codevs3732. 题目大意:已知多项式方程: 求这个方程在[1, m]内的整数解(n 和 m 均为正整数). 解题思路:因为$0=0$(废话),能得出$0+x·p\equiv 0(mod\ p)$. 也就是当方程右边为0时,方程左边mod p为0. 但方程左边mod p等于0时,方程右边不一定等于0. 但是也不一定不等于0. 所以我们如果多引入几个p(最好是素数),对其进行测试,发现都为0的话,那我们就可以认为它

【BZOJ 3751】 [NOIP2014]解方程

3751: [NOIP2014]解方程 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 914  Solved: 173 [Submit][Status][Discuss] Description 已知多项式方程: a0+a1*x+a2*x^2+...+an*x^n=0 求这个方程在[1,m]内的整数解(n和m均为正整数). Input 第一行包含2个整数n.m,每两个整数之间用一个空格隔开. 接下来的n+1行每行包含一个整数,依次为a0,a1,

在洛谷3369 Treap模板题 中发现的Splay详解

本题的Splay写法(无指针Splay超详细) 前言 首先来讲...终于调出来了55555...调了整整3天..... 看到大部分大佬都是用指针来实现的Splay.小的只是按照Splay的核心思想和原理来进行的.可能会有不妥之处,还请大佬们指出,谢谢! 那么这个题解存在的意义就是让不会敲Splay的人额...会敲Splay啦... 基本思想 数据结构 对于Splay,我定义了一个class类(当成struct就行啦...个人习惯不同啦),定义名称为“Splay”. 之后在类中,我定义了Splay