Ned的难题
题目描述
Ned再也看不下去Robert的种种恶习,于是他决定出一道题来让他醒悟。
Ned的题目是这样:
给出一个有n个数的序列,求其中所有连续子序列的数的最大公因数的乘积模1000000009的值。
Robert当时就立刻给出了一个超级无敌速度无人能及的O(1)错误解法。
既然Robert不会做,Ned决定让你来做出这题来证明Robert不应颓废下去。
输入
第一行一个正整数n(1≤n≤50000)
第二行n个正整数a[i](1≤a[i]≤10000000)
输出
一行一个整数表示序列中所有连续子序列的数的最大公因数的乘积模1000000009的值
样例输入
3
4 6 2
样例输出
384
样例解释
gcd(4,6,2)*gcd(4,6)*gcd(6,2)*gcd(4)*gcd(6)*gcd(2)=2*2*2*4*6*2=384
数据范围
对于20%的数据:
1≤n≤1000
对于额外20%的数据保证不存在长于2000的数列的最大公约数大于一
对于100%的数据:
1≤n≤50000
1≤a[i]≤10000000
【题解】
(题外话:考试时我不记得求一群数的最大公约数怎么弄了。。。下考后发现我智障了:不就是先求两个数的最大公因数,再拿求出的数与第三个数求最大公因数吗!!!)
所以某个质数p对答案的贡献跟一个子序列里这个质数的次数的最小值有关,即p^min(a[i]),观察到最终求的是gcd的乘积,所以,我们可以现将所有数分解质因数,然后对于一个质数对某个区间的答案的贡献,其实就是这个区间内这个质数的次数的最小值,所以我们可以用笛卡尔树加上快速幂来解决,时间复杂度O(8nlogn)(注,有常数8是因为每个小于10^7数最多可以被分成八个不同的质因数)。
然而出题人的题解也太高大上了吧。。。笛卡尔树是什么毛线???
于是我就想出了一种鬼畜的解法:
从前往后求1~i序列的最大公约数n,当前搜到了i,若搜到一个数时,序列的最大公约数突然变成n/j,则说明1~i-1中j为该序列的公约数,然后这i-1个数中必定有(i-1)* (i-1-1)/2对公约数中有此数,因此答案可乘上这个数的(i-1)*(i-1-1)/2次方(快速幂),再把这i-1个数除上j即可。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int mod=1e9+9;
ll n,a[50005]={},ans=1;
ll gcd(ll a,ll b)//求最大公约数
{
return a==0?b:gcd(b%a,a);
}
ll Pow(ll a,ll b)//快速幂
{
if(b==1)return a;
ll s=Pow(a,b>>1);
s=s*s%mod;
if(b&1) s=s*a%mod;
return s;
}
il ll gi()
{
re ll x=0;
re ll t=1;
re char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*t;
}
int main()
{
freopen("ned.in","r",stdin);
freopen("ned.out","w",stdout);
n=gi();
fp(i,1,n)
a[i]=gi();
a[++n]=1;//有一种情况:搜到最后时,gcd不为0,这时未加特判的程序会直接退出,留下公约数没处理
ll gg,ggg;
fp(i,1,n)
{
if(a[i]==1) continue;
ll cnt=1;
gg=a[i];
fp(j,i+1,n)
{
cnt++;
ggg=gcd(min(gg,a[j]),max(gg,a[j]));
if(gg!=ggg)
{
ll tt=gg/ggg;
ans=ans*Pow(tt,cnt*(cnt-1)/2)%mod;
fp(k,i,j-1) a[k]/=tt;
gg=ggg;
}
if(ggg==1) break;//没必要再看了,都互质了
}
}
printf("%lld\n",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
Ned的难题的更多相关文章
- Ned 的难题
题目描述 Ned 再也看不下去 Robert 的种种恶习, 于是他决定出一道题来让他醒悟. Ned 的题目是这样: 给出一个有 n 个数的序列, 求其中所有连续子序列的数的最大公因数的乘积模 1000 ...
- 深入super,看Python如何解决钻石继承难题 【转】
原文地址 http://www.cnblogs.com/testview/p/4651198.html 1. Python的继承以及调用父类成员 python子类调用父类成员有2种方法,分别是普通 ...
- 探讨webapp的SEO难题(上)
前言 网络蜘蛛无法解析javascript,至少百度是不能的,神马搜索差的更远,而我们的webapp的渲染展示完全由javascript驱动 所以蜘蛛访问webapp页面会得到一个白页面,比如,我们期 ...
- hduoj 1251 统计难题
http://acm.hdu.edu.cn/showproblem.php?pid=1251 统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory ...
- FZU 1686 神龙的难题 (重复覆盖)
Problem 1686 神龙的难题 Accept: 397 Submit: 1258Time Limit: 1000 mSec Memory Limit : 32768 KB Prob ...
- HDU 1251统计难题
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submi ...
- hdu 1251 统计难题 (字典树入门题)
/******************************************************* 题目: 统计难题 (hdu 1251) 链接: http://acm.hdu.edu. ...
- hdu1251 统计难题
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=1251 题目: 统计难题 Time Limit: 4000/2000 MS (Java/Othe ...
- UOJ #10 pyx的难题
pyx的难题 被这题搞得生无可恋. 容易看出 题目完成时间与优先级之间的关系是单调的,故可以二分答案. 用于二分的答案可以取\(O(n)\)个离散值, 这样就很方便地保证了优先级各不相同. 可以用优先 ...
随机推荐
- js统计图表插件 Echarts
Echarts 用于制作数据统计图表,一个纯 Javascript 的图表库,快捷简便的生成统计图表. 官网:https://www.echartsjs.com/ 效果 html <!DOCTY ...
- 在添加新内容时,creatat没有数据
首先找到controller中的add方法,然后是执行了Service.insert()方法 然后找到service对应的impl方法, impl方法中的 public void insert(Cus ...
- 【Redis】三、Redis安装及简单示例
(四)Redis安装及使用 Redis的安装比较简单,仍然和大多数的Apache开源软件一样,只需要下载,解压,配置环境变量即可.具体安装过程参考:菜鸟教程Redis安装. 安装完成后,通过r ...
- JAVA基础——集合Iterator迭代器的实现
一.迭代器概述 1.什么是迭代器? 在Java中,有很多的数据容器,对于这些的操作有很多的共性.Java采用了迭代器来为各种容器提供了公共的操作接口.这样使得对容器的遍历操作与其具体的底层实现相隔离, ...
- KOA的简易模板引擎实现方式
上上一期链接--也就是本文的基础,参考KOA,5步手写一款粗糙的web框架 上一期链接--有关Router的实现思路,这份Koa的简易Router手敲指南请收下 本文参考仓库:点我 上一期科普了Rou ...
- tab下拉显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- WIndows 系统下的常用命令 和 检测方法
### 一.检测硬盘速度(Windows 自带工具) #### 使用windows 系统自带的工具测试硬盘读写速度 > 在使用下面命令前,需要获得管理员权限,才会在Dos窗口上显示(否则,一闪而 ...
- static private 与 final 的用法总结
1.static表示静态.他是属于类的.可以在本身类里直接调用,或在其它类里用类名.方法名调用.不加static表示是实例的方法,必须用实例来调用.在本类里也一样,必须用实例调用 2.private是 ...
- How to read and write multiple files in Python?
Goal: I want to write a program for this: In a folder I have =n= number of files; first read one fil ...
- C++ 输入外挂
inline int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch> ...