【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,a2,...,an。

Output

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

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

Sample Input

2 10

2

-3

1

Sample Output

2

1

2

哈希+拉格朗日定理

取一个质数p,求出方程在模p意义下的解,根据拉格朗日定理,有不超过n个解。

然后用在模p意义下的解每次加上p(在模p意义下仍是解),在模另一个大质数下判断是否是解,如果是的话,那么基本可以断定这个值就是解了。

此时复杂度为O(n^2*m/p),当p取到sqrt(m*n)附近时,时间复杂度为O(n*sqrt(m*n))

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#define LL long long
using namespace std;
int tot=0,p[4],v[1000005],n,m;
char s[10005];
LL a[4][105];
void Change(char *s,int k)
{
	int fu=1,i=0;
	int l=strlen(s);
	for (int j=1;j<=2;j++)
	{
		i=0;
		if (s[0]=='-') fu=-1,i=1;
 	    for (;i<l;i++)
			a[j][k]=a[j][k]*10LL%p[j]+s[i]-'0';
		if (fu==-1)
			a[j][k]=p[j]-a[j][k];
	}
}
int Calc(int x,int k)
{
	LL ans=0,b=1;
	for (int i=0;i<=n;i++)
		ans=(ans+1LL*a[k][i]*b)%p[k],b=1LL*b*x%p[k];
	return ans%p[k];
}
int main()
{
	p[1]=67891,p[2]=1000000207;
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
		v[i]=0;
	for (int i=0;i<=n;i++)
		scanf("%s",s),Change(s,i);
	for (int i=1;i<=p[1];i++)
	{
		if (Calc(i,1)!=0) continue;
		for (int j=i;j<=m;j+=p[1])
			if (Calc(j,2)==0)
				v[j]=1;
	}
	int tot=0;
	for (int i=1;i<=m;i++)
		if (v[i])
			tot++;
    printf("%d\n",tot);
	for (int i=1;i<=m;i++)
		if (v[i])
			printf("%d\n",i);
	return 0;
}

TLE都是因为p取得太小。

时间: 2024-11-04 15:34:58

【BZOJ 3751】 [NOIP2014]解方程的相关文章

[BZOJ 3751][NOIP2014]解方程(哈希)

Description 已知多项式方程: a0+a1*x+a2*x^2+...+an*x^n=0 求这个方程在[1,m]内的整数解(n和m均为正整数). Solution 一道很久很久以前就应该做的noip的题 一定要放上来是要见证我人品崩坏的一下午 生无可恋…QAQ 题解其实也很简单啦 随便找几个素数取模验证是不是等于0就好了 随便 随便 随便 随便找几个…素数 在WA\TLE\OLE间切换,最后还是抄了别人的几个素数 怀疑人生[望天 (BZOJ上的数据是加强了的,如果是ccf的数据那当然就随

BZOJ 3751 [NOIP2014]解方程

题解:运用筛法的思想,%p意义下,F(x)!=0则F(x+p)!=0 多选几个质数把F(x)!=0的筛去就可以了 #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m; int ans; int vis[1000009]; int p[51]={0,30011,11261,14843,19997,21893}; int a[200][51]; void Min

【bzoj3751】[NOIP2014]解方程 数论

题目描述 已知多项式方程: a0+a1*x+a2*x^2+...+an*x^n=0 求这个方程在[1,m]内的整数解(n和m均为正整数). 输入 第一行包含2个整数n.m,每两个整数之间用一个空格隔开. 接下来的n+1行每行包含一个整数,依次为a0,a1,a2,...,an. 输出 第一行输出方程在[1,m]内的整数解的个数. 接下来每行一个整数,按照从小到大的顺序依次输出方程在[1,m]内的一个整数解. 样例输入 2 10 2 -3 1 样例输出 2 1 2 题解 真心不难的数论题 首先高精度

NOIP2014解方程

题目:求一个n次整系数方程在1-m内的整数解  n<=100 系数<=10000位 m<=100W 题解:最暴力的想法是枚举x,带入求值看是否为0. 这样涉及到高精度乘高精度,高精度乘单精度,高精度加高精度和高精度减高精度. 复杂度 n*m*len*len ,显然只能过30%的数据 让我们考虑优化: 我们先来研究一下这个算法的主要耗时在哪里 1)将x带入方程左边求值 2)选择多少x带入 我们考虑第一个优化 1)秦九韶算法 只要我们把原方程左边化为 ((An*x+An-1)*x+An-2)

noip2014 解方程(本博文转载于http://blog.csdn.net/popoqqq/article/details/40984859,略有删减)

首先阿贝尔在200年前告诉我们 五次以上方程没有求根公式 于是我们只能枚举1~m 这个是100W 然后100W再加上1W位的精度 都不用运算直接就是跪…… 怎么办呢QAQ 哈希大法好! 令f(x)=an*x^n+...+a1*x^1+a0*x^0 易知若f(x)=0 则f(x) mod p=0 反之如果f(x) mod p=0 那么我们基本可以得出f(x)=0 p比较靠谱的时候碰撞率极低 所以我们把所有的ai都对p取模 然后对于每个解O(n)验证即可 这样是O(m*n)=10 8 (不是一秒么

[noip2014]解方程 hash+秦九昭

坑啊= = 选了好几次质数,发现还是这一组靠谱 思路:每次mod之后求出所有解,再mod再求,看着复杂度差不多了就把没重复的都输出就行了 const mi:array[1..7] of int64=(12537,15437,17647,14677,10003,10009,10007); var n,m,shi,sum,x:int64; i,j,k,y1:longint; a:array[-1..102,-1..10000+9] of int64; flag:array[-1..1000000+9

NOIP2014 解方程

描述 已知多项式方程: a0+a1x+a2x2+...+anxn=0a0+a1x+a2x2+...+anxn=0 求这个方程在[1, m]内的整数解(n 和 m 均为正整数). 格式 输入格式 输入共 n+2 行. 第一行包含 2 个整数 n.m,每两个整数之间用一个空格隔开. 接下来的 n+1 行每行包含一个整数,依次为a0,a1,a2,...,ana0,a1,a2,...,an. 输出格式 第一行输出方程在[1, m]内的整数解的个数. 接下来每行一个整数,按照从小到大的顺序依次输出方程在[

【秦九韶算法】【字符串哈希】bzoj3751 [NOIP2014]解方程

在模意义下枚举m进行验证,多设置几个模数,而且小一些,利用f(x+p)%p=f(x)%p降低计算次数.UOJ AC,bzoj OLE. #include<cstdio> #include<iostream> #include<cstring> #include<vector> using namespace std; #define MAXV 4951 vector<int>v; typedef unsigned int ull; const u

BZOJ3751: [NOIP2014]解方程

既然bzoj上有这道题了就把这个坑填了吧... 题解见:http://blog.csdn.net/popoqqq/article/details/40984859 话说这个解法如果当时想到冲突的概率很小的话应该就能想出来233 代码: 1 #include<cstdio> 2 3 #include<cstdlib> 4 5 #include<cmath> 6 7 #include<cstring> 8 9 #include<algorithm>