【BZOJ2742】【HEOI2012】Akai的数学作业 [数论]
Akai的数学作业
Time Limit: 10 Sec Memory Limit: 128 MB
[Submit][Status][Discuss]
Description
这里是广袤无垠的宇宙这里是一泻千里的银河,这里是独一无二的太阳系,这里是蔚蓝色的地球
这里,就是这里,是富饶的中国大陆!
这里是神奇的河北大地,这里是美丽的唐山,这里是神话般的唐山一中,这里是Akai曾经的教室
黑板上还留有当年Akai做过的数学作业,其实也并不是什么很困难的题目:
“
给出一个一元n次方程:
a0 + a1x + a 2 x2 +…+ anxn= 0
求此方程的所有有理数解。
”
Akai至今还深刻记得当年熬夜奋战求解的时光,他甚至还能记得浪费了多少草稿纸。
但是却怎么也想不起来最后的答案是多少了,你能帮助他么?
Input
Output
Sample Input
-24 14 29 6
Sample Output
-4
-3/2
2/3
HINT
对于30%的数据,n <= 10
对于100%的数据,n <= 100,|a i| <= 2*10^7,an ≠ 0
Main idea
给出一个一元n次方程:A0+A1*x+A2*x^2+…+An*x^n,求出这个方程的所有有理数解。
Solution
这必然是一道数论题。首先我们发现了题目的一个非常重要的特征:求的是有理数解。
立马想到了分解因式,因为要的是有理数解,所以原方程肯定可以表示成:
x就是q/p。
然后再来思考一下。我们先从最简单的情况开始处理,也就是A0≠0,An≠0的情况。
显然可以知道p一定是An分出来的,q一定是A0分出来的,那么一定有p是An的约数,q是A0的约数,那么这时候所有的情况就应该是
仔细推一下式子,发现了一个规律:几个约数相乘的情况所表达出的集合和不考虑相乘情况的集合是一样的!那么处理就简单了很多。
由于可能有前几项系数=0的情况,所以我们从A0的想法出发,找到第一个系数非0的项将这一项的约数存下来(如果不是A0的话则在答案中加一个0),然后从后往前找找到第一个非0的存下它的约数。然后O(约数个数)^2枚举任意两种情况的q/p放到原式里面判断(答案有可能是负数所以还要检查一下-q/p可不可行)然后在检查的时候发现了一个问题,数字要么精度误差过大要么就是爆出int范围了,我们想到了通分,分子分母同乘上p^n,避免了精度问题。
以n=3的举个例子:将原式
转化为
然后我们就可以不管分母了,用这样的方法解决了精度问题。那么怎么解决爆int范围的问题呢?我们发现,在每次操作的时候都对一个质数取模的话错解的几率不是非常大,那么我们就可以大胆地取模几个质数来判断,如果不放心可以多取模几个。
BearChild发现了一个神奇的质数:50033(如果使用这个质数的话是不需要用其余几个质数判断的)。
这样进行累加和是否为0的判断,可行的话将每个答案存下来,然后sort一遍输出即可。
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; const int ONE=;
const int MOD=; int n;
int A[ONE];
int divisor[ONE][],num[];
int p[ONE];
int q[ONE];
int Repeat[ONE];
int cnt; struct power
{
int l,r;
int value;
}a[ONE]; int cmp(const power &a,const power &b)
{
return (double)a.l/a.r < (double)b.l/b.r;
} int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int gcd(int a,int b)
{
int r=a%b;
while(r)
{
a=b;
b=r;
r=a%b;
}
return b;
} void Deal(int x,int PD)
{
for(int i=;i<=x;i++)
{
if(!(x%i)) divisor[++num[PD]][PD]=i;
}
} int Check(int x,int y)
{
p[]=q[]=;
for(int i=;i<=n;i++)
{
p[i]=(long long)p[i-]*y % MOD; q[i]=(long long)q[i-]*x % MOD;
} long long res=;
for(int i=;i<=n;i++)
{
res=(res+(long long)p[n-i]*q[i]*A[i]) % MOD;
} if(!res) return ;
return ;
} int main()
{
n=get();
for(int i=;i<=n;i++) A[i]=get();
if(A[]==)
{
a[++cnt].l=; a[cnt].r=;
}
for(int i=;i<=n;i++)
{
if(A[i])
{
Deal(abs(A[i]),);
break;
}
} for(int i=n;i>=;i--)
{
if(A[i])
{
Deal(abs(A[i]),);
break;
}
} for(int i=;i<=num[];i++)
for(int j=;j<=num[];j++)
{
int x=divisor[i][];
int y=divisor[j][];
if(gcd(x,y)!=) continue;
if(Check(x,y))
{
a[++cnt].l=x;
a[cnt].r=y;
}
if(Check(-x,y))
{
a[++cnt].l=-x;
a[cnt].r=y;
}
} sort(a+,a+cnt+,cmp);
printf("%d\n",cnt);
for(int i=;i<=cnt;i++)
{
if(a[i].r==) printf("%d\n",a[i].l);
else printf("%d/%d\n",a[i].l,a[i].r);
} }
【BZOJ2742】【HEOI2012】Akai的数学作业 [数论]的更多相关文章
- [BZOJ2742][HEOI2012]Akai的数学作业[推导]
题意 给定各项系数,求一元 \(n\) 次方程的有理数解. \(n\leq 100\). 分析 设答案为 \(\frac{p}{q}\) ,那么多项式可以写成 \(a_0\frac{p}{q}+a_1 ...
- BZOJ 2742: [HEOI2012]Akai的数学作业
2742: [HEOI2012]Akai的数学作业 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 535 Solved: 226[Submit][S ...
- LuoguP5390 [Cnoi2019]数学作业(数论)
转进制,然后发现贡献只有\(1_{(2)}\),取奇数个的子集方案是\(2^{n-1}\) #include <iostream> #include <cstdio> #inc ...
- 洛谷P3216 [HNOI2011] 数学作业 [矩阵加速,数论]
题目传送门 数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N和 M,要求计算 Concatenate (1 .. N)Mod M 的值,其中 C ...
- BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘
2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...
- bzoj2326: [HNOI2011]数学作业
矩阵快速幂,分1-9,10-99...看黄学长的代码理解...然而他直接把答案保存在最后一行(没有说明...好吧应该是我智障这都不知道... #include<cstdio> #inclu ...
- BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )
BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...
- CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)
CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...
- [luogu P3216] [HNOI2011]数学作业
[luogu P3216] [HNOI2011]数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M,要求计算 Concatenate (1 ...
随机推荐
- 解析HTML利器AngleSharp介绍
解析HTML利器AngleSharp介绍 AngleSharp是基于.NET(C#)开发的专门为解析xHTML源码的DLL组件. 项目地址:https://github.com/FlorianRapp ...
- 微信营销 推广 会议签到 活动签到 复用微信3D动画签到系统
适用场合 本软件适合各行各业,尤其世界500强上市公司,推广产品,聚集微信粉丝和人气.如大型展销会,新产品发布,主题活动推广,年会晚会等.各种商业和演出场合. 软件有试用版可供下载试用. 特色功能 顾 ...
- 第五篇Python基本数据类型
运算符 1. 结果是具体的值:算数运算符和赋值运算符 算数运算符:+.-.*./.**(幂).%(取余).//(取商) print(3-2) # 减法 print(3*2) # 乘法 print(3/ ...
- python接口测试(一)——http请求及token获取
使用python对当前的接口进行简单的测试 1.接口测试是针对软件对外提供服务得接口得输入输出进行得测试,验证接口功能与接口描述文档得一致性 返回结果可以为字符串,json,xml等 2.接口的请求方 ...
- AcCoder Contest-115 D - Christmas
D - Christmas Time limit : 2sec / Memory limit : 1024MB Score : 400 points Problem Statement In some ...
- 九度OJ--Q1167
import java.util.Scanner;import java.util.TreeSet; /* * 题目描述: * 输入一个数组的值,求出各个值从小到大排序后的次序. * 输入: * 输入 ...
- Windows server 2012 R2开机进入cmd,关闭后黑屏问题
原因分析: 因为自己在卸载IIS的时候,不小心卸载了.net framework,系统没有了图形界面(由完整模式Full变为了核心模式core),需要重新恢复.net framework4.5. 解决 ...
- Spark实战练习02--处理分隔符
一.场景 devicestatus.txt 文件包含了来自于不同运营商的移动设备的数据,不同的数据格式,包括设备ID.当前状态.位置等等.注意,该文件中的记录具有不同的字段分隔符:一些使用逗号,一些使 ...
- UVA 11883 Repairing a Road(最短路径+暴力枚举)
You live in a small town with R bidirectional roads connecting C crossings and you want to go from c ...
- 数论3——gcd&&lcm
gcd(a, b),就是求a和b的最大公约数 lcm(a, b),就是求a和b的最小公倍数 然后有个公式 a*b = gcd * lcm ( gcd就是gcd(a, b), ( •̀∀•́ ) ...