2742: [HEOI2012]Akai的数学作业

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 535  Solved: 226
[Submit][Status][Discuss]

Description

这里是广袤无垠的宇宙这里是一泻千里的银河
这里是独一无二的太阳系
这里是蔚蓝色的地球
这里,就是这里,是富饶的中国大陆!
这里是神奇的河北大地
这里是美丽的唐山
这里是神话般的唐山一中
这里是Akai曾经的教室
黑板上还留有当年Akai做过的数学作业,其实也并不是什么很困难的题目:
 
给出一个一元n次方程:
a0 + a1x + a    2   x2 +…+ anxn= 0
求此方程的所有有理数解。
 
Akai至今还深刻记得当年熬夜奋战求解的时光
他甚至还能记得浪费了多少草稿纸
但是却怎么也想不起来最后的答案是多少了
你能帮助他么?

Input

第一行一个整数n。第二行n+1个整数,分别代表a    0 到a n

Output

第一行输出一个整数t,表示有理数解的个数
接下来t行,每行表示一个解
解以分数的形式输出,要求分子和分母互质,且分母必须是正整数特殊的,如果这个解是一个整数,那么直接把这个数输出
等价的解只需要输出一次
所有解按照从小到大的顺序输出

Sample Input

3
-24 14 29 6

Sample Output

3
-4
-3/2
2/3

HINT

【数据范围】

对于30%的数据,n<=10

对于100%的数据,n <= 100,|a i| <= 2*10^7,an≠ 0

Source

[Submit][Status][Discuss]

好神的一道HEOI题。

据LH讲,有个定理叫做多项式高斯引理什么的,大概就是讲,复数域下的一个关于$x$的$n$次多项式$f(x)=a_{0}+a_{1}x+a_{2}x^{2}+a_{3}x^{3}+...+a_{n}x^{n}$一定可以分解成$n$个含$x$的一次多项式相乘,即$f(x)$一定存在一种形如$f(x)=\prod{(b_{i}x+c_{i})}$的表示,其中每个式子都会产生一个复数域下的根(当然,这些根有可能重复)。这道题叫我们只用考虑有理数根,所以可以把式子改写为$f(x)=g(x)*\prod{(b_{i}x+c_{i})}$的样子,其中g(x)是一个关于$x$的多项式,包含了所有的非有理数根,剩下的部分就表示了所有的有理数根。发现每个有理数根都能表示成$x_{i}=\frac{c_{i}}{b_{i}}$,然后不难发现$f(x)=\sum_{i=0}^{n}{a_{i}x^{i}}$中的$a_{0}$包含了所有的$c_{i}$,而$a_{n}$包含了有所的$b_{i}$,所以对于所有的合法有理数根$x_{i}=\frac{c_{i}}{b_{i}}$,$c_{i}$一定是$a_{0}$的约数,$b_{i}$一定是$a_{n}$的约数。所以可以先处理出$a_{0}$和$a_{n}$的所有约数,然后暴力枚举$b_{i}$和$c_{i}$,$O(N)$check是否合法即可。check的方式是,对于$x=\frac{p}{q}$,$f(x)=\sum_{i=0}^{n}{a_{i}p^{i}q^{n-i}}$,在模意义下检查是否为$0$即可。

 #include <bits/stdc++.h>

 template <class T>
T gcd(T a, T b)
{
return b ? gcd(b, a % b) : a;
} typedef long long lnt; const int mxn = ;
const int mxm = ;
const lnt mod = ; int n, s[mxn]; struct number
{
int a, b, f; // ans = a / b number(void) {};
number(int x, int y, int g = )
: a(x), b(y), f(g) {}; void print(void)
{
if (f == -)
putchar('-');
if (a % b)
printf("%d/%d\n", a, b);
else
printf("%d\n", a / b);
}
}ans[mxm]; int tot; bool cmp(const number &A, const number &B)
{
if (A.f == - && B.f == +)
return true;
if (A.f == + && B.f == -)
return false;
if (A.f == + && B.f == +)
return 1LL * A.a * B.b < 1LL * B.a * A.b;
if (A.f == - && B.f == -)
return 1LL * A.a * B.b > 1LL * B.a * A.b;
} void leadingZeros(void)
{
int cnt = ; while (!s[cnt])
++cnt; if (cnt)
{
n = n - cnt; for (int i = ; i <= n; ++i)
s[i] = s[i + cnt]; ans[tot++] = number(, );
}
} int divA[mxm], sizA;
int divB[mxm], sizB; void divide(int x, int *div, int &siz)
{
if (x < )x = -x; siz = ; int t = int(sqrt(x)); for (int i = ; i <= t; ++i)
if (x % i == )
{
div[siz++] = i;
div[siz++] = x / i;
} if (t * t == x)--siz;
} int powA[mxn];
int powB[mxn]; void check(lnt a, lnt b, lnt f)
{
powA[] = powB[] = 1LL; for (int i = ; i <= n; ++i)
{
powA[i] = (powA[i - ] * a) % mod;
powB[i] = (powB[i - ] * b) % mod;
} lnt sum = , tmp; for (int i = ; i <= n; ++i)
{
tmp = s[i];
tmp = (tmp * powA[i]) % mod;
tmp = (tmp * powB[n - i]) % mod; if (i & )tmp = (tmp * f + mod) % mod; sum = (sum + tmp) % mod;
} if (sum == )ans[tot++] = number(a, b, f);
} signed main(void)
{
scanf("%d", &n); for (int i = ; i <= n; ++i)
scanf("%d", s + i); leadingZeros(); divide(s[], divA, sizA);
divide(s[n], divB, sizB); for (int i = ; i < sizA; ++i)
for (int j = ; j < sizB; ++j)
{
int a = divA[i];
int b = divB[j]; if (gcd(a, b) == )
{
check(a, b, +);
check(a, b, -);
}
} std::sort(ans, ans + tot, cmp); printf("%d\n", tot); for (int i = ; i < tot; ++i)
ans[i].print();
}

@Author: YouSiki

BZOJ 2742: [HEOI2012]Akai的数学作业的更多相关文章

  1. [BZOJ2742][HEOI2012]Akai的数学作业[推导]

    题意 给定各项系数,求一元 \(n\) 次方程的有理数解. \(n\leq 100\). 分析 设答案为 \(\frac{p}{q}\) ,那么多项式可以写成 \(a_0\frac{p}{q}+a_1 ...

  2. 【BZOJ2742】【HEOI2012】Akai的数学作业 [数论]

    Akai的数学作业 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 这里是广袤无垠的宇宙这里 ...

  3. BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )

    BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...

  4. BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘

    2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...

  5. bzoj2326: [HNOI2011]数学作业

    矩阵快速幂,分1-9,10-99...看黄学长的代码理解...然而他直接把答案保存在最后一行(没有说明...好吧应该是我智障这都不知道... #include<cstdio> #inclu ...

  6. CJOJ 1331 【HNOI2011】数学作业 / Luogu 3216 【HNOI2011】数学作业 / HYSBZ 2326 数学作业(递推,矩阵)

    CJOJ 1331 [HNOI2011]数学作业 / Luogu 3216 [HNOI2011]数学作业 / HYSBZ 2326 数学作业(递推,矩阵) Description 小 C 数学成绩优异 ...

  7. [luogu P3216] [HNOI2011]数学作业

    [luogu P3216] [HNOI2011]数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M,要求计算 Concatenate (1 ...

  8. P3216 [HNOI2011]数学作业 (矩阵快速幂)

    P3216 [HNOI2011]数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 NN 和 MM ,要求计算 Concatenate (1 .. N ...

  9. [HNOI2011]数学作业 --- 矩阵优化

    [HNOI2011]数学作业 题目描述: 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算\(Concatenate(1..N)\; Mod\; ...

随机推荐

  1. 《杜增强讲Unity之Tanks坦克大战》3-添加坦克

    3 添加坦克 3.1 本节效果预览   3.2 另存新场景 首先打开上次的场景s1,另存为s2,放到同一个文件夹下面.   3.3 添加坦克模型 在Model文件夹下面找到Tank模型   将Tank ...

  2. java四种访问权限修饰符

    java中四个访问权限修饰符: public(公开的).protected(受保护的).default(默认的).private(私有的). 它们决定了紧跟其后被定义的东西的使用范围. 适用范围< ...

  3. jsp servlet路径问题

    最近做小作业时饱受路径问题的困扰,记录一下: 当工程目录如上所示时,路径应该这么写: 情况1:根目录下 login.jsp中的表单提交给Servlet时,可以直接写Servlet名: <form ...

  4. OSSEC 架构

    OSSEC由很多部分组成,它有一个集中的管理端,用于监控.并接收来自代理.syslog.数据库或无代理设备的日志. 管理端(服务器) 管理端属于OSSEC部署中的中心部分.它存储了文件完整性检测数据库 ...

  5. sync命令详解

    转:https://blog.csdn.net/everything1209/article/details/50423679 1.谁和谁同步? 2.为什么要同步?复制移动的过程不是同步的吗,都发生了 ...

  6. export命令详解

    基础命令学习目录首页 export 的基本作用就是将父shell中的局部变量设置为环境变量,使得该变量可以在子shell中使用.下面设置两种情景对export进行原理解析. 情景  1. 有一个名为m ...

  7. Python基础系列讲解——TCP协议的socket编程

    前言 我们知道TCP协议(Transmission Control Protocol, 传输控制协议)是一种面向连接的传输层通信协议,它能提供高可靠性通信,像HTTP/HTTPS等网络服务都采用TCP ...

  8. 使用socket发送http请求(get/post)

    手动发送http请求 解释说明 https://blog.csdn.net/zhangliang_571/article/details/23508953 http://www.cnblogs.com ...

  9. C++ Style Languages: C++, Objective-C, Java, C#

    Hyperpolyglot.org From Hyperpolyglot.org C++ Style Languages: C++, Objective-C, Java, C# a side-by-s ...

  10. C++ 函数 引用

    一.引用的概念 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样.引用的声明方法: 类型标识符 &引用名 = 目标变量名: 为一个变量起一个别名.假如有一个变量a,想给 ...