洛谷 P5502 - [JSOI2015]最大公约数(区间 gcd 的性质+分治)
学校模拟赛的某道题让我联想到了这道题……
先讲一下我的野鸡做法。
首先考虑分治,对于左右端点都在 \([L,R]\) 中的区间我们将其分成三类:完全包含于 \([L,mid]\) 的区间,完全包含于 \([mid+1,R]\) 的区间,和跨过中间点的区间。前两种我们只需进一步递归 \([L,mid]\) 和 \([mid+1,R]\) 即可求解出答案,比较麻烦的是第三种。我们考虑先扫一遍预处理出 \(F_i=\gcd(a_i,a_{i+1},\cdots,a_{mid})\),以及 \(G_i=\gcd(a_{mid+1},a_{mid+2},\cdots,a_{i})\),那么对于一个满足 \(l\in[L,mid],r\in[mid+1,R]\),其权值 \(W(l,r)=(r-l+1)·\gcd(F_l,G_r)\),直接枚举依然不可做,不过注意到 \(F_i,G_i\) 不同数的种类不超过 \(\log a_i\) 种,因此考虑对 \(F_i,G_i\) 相同的值,我们只保留其最靠左(右)的一个,然后暴力枚举更新答案即可。这个时间复杂度的计算要动点脑筋,乍一看是 \(n\log^3n\) 的(包括我一开始做这道题时也这么认为),但今天才发现它其实是 2log 的,不妨设 \(n\) 为 \(2\) 的整数次幂,\(n\) 不是 \(2\) 的整数次幂的情况与其最近的 \(2\) 的整数次幂效率上显然只是常数的差别。首先求 \(F_i,G_i\) 肯定是 2log 的,区间长度 1log + gcd 1log,比较棘手的是暴力枚举复杂度是什么,若区间长度 \(<\log n\),那么枚举次数的上界肯定是区间长度的平方,\(T_1=\sum\limits_{i=2^k,k\in\mathbb{Z},i\le\log n}\dfrac{n}{i}·i^2=\sum\limits_{i=2^k,k\in\mathbb{Z},i\le\log n}ni\),又 \(i\) 为 \(2\) 的整数次幂,根据等比数列求和公式,后面那东西是 \(\mathcal O(n\log n)\) 的,若区间长度 \(>\log n\),那么对于长度为 \(i\) 的区间,单次枚举复杂度 \(\log^2n\),而这样的区间最多 \(\dfrac{n}{i}\) 个,因此复杂度就是 \(T_2=\log^2n\sum\limits_{i>\log n,i=2^k,k\in\mathbb{Z}}\dfrac{n}{i}\),还是根据等比数列求和公式,后面的 \(\sum\) 里的东西是 \(\mathcal O(\dfrac{n}{\log n})\) 级别的,因此总枚举次数是 \(\mathcal O(n\log n)\) 的,再加上 gcd 的 \(\mathcal O(\log n)\),总复杂度就是 \(\mathcal O(n\log^2n)\)
const int MAXN=1e5;
ll gcd(ll x,ll y){return (!y)?x:gcd(y,x%y);}
int n;ll a[MAXN+5],ans=0,pre[MAXN+5],suf[MAXN+5];
void solve(int l,int r){
if(l==r) return chkmax(ans,a[l]),void();
int mid=l+r>>1;solve(l,mid);solve(mid+1,r);
for(int i=l;i<=r;i++) pre[i]=suf[i]=0;
for(int i=mid;i>=l;i--) suf[i]=gcd(suf[i+1],a[i]);
for(int i=mid+1;i<=r;i++) pre[i]=gcd(pre[i-1],a[i]);
vector<pair<ll,int> > v1,v2;
for(int i=l;i<=mid;i++) if(i==l||(suf[i]^suf[i-1])) v1.pb(mp(suf[i],mid-i+1));
for(int i=mid+1;i<=r;i++) if(i==r||(pre[i]^pre[i+1])) v2.pb(mp(pre[i],i-mid));
for(int i=0;i<v1.size();i++) for(int j=0;j<v2.size();j++) chkmax(ans,gcd(v1[i].fi,v2[j].fi)*(v1[i].se+v2[j].se));
}
int main(){
scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
solve(1,n);printf("%lld\n",ans);
return 0;
}
事实上有一个非常 simple 的复杂度也是 2log 的做法,我们固定左端点,那么随着右端点的变化,\(\gcd\) 最多变化 \(\log a_i\) 次,那么我们可以二分找出这 \(\log a_i\) 次的断点,然后每次取断点左边的点更新答案即可,求区间 \(\gcd\) 可以 ST 表,复杂度 \(n\log^2n\)。
最后稍微总结一下这道题带给我们的启示:
- 碰到像区间 gcd 这样固定住左端点,随着右端点的增大,区间权值变化量很小(一般 \(\log n\) 级别)的权值函数,可以考虑二分权值变化的位置,这样即可将 \([1,r]\) 拆分成一段段区间,每段区间内所有 \(l\) 都有 \([l,r]\) 权值相同,这样就比较好维护答案(我记得之前某场模拟赛还有这样一个问题:给定长度为 \(n\) 的数列,要你将序列分成 \(k\) 段,求每段 bitwise or 值之和的最大值,当时一点思路都没有,现在知道了这个技巧,学了 wqs 二分,不就得心应手了?)有时还可以利用排序后差分数组的 gcd 与原数组差分数组的 gcd 相同这一性质进行转化,并运用区间 gcd 的性质维护,具体应用就是校内模拟赛那道题,隐私起见就不把题面亮在这里了(
- 碰到求满足条件的区间个数,或者要你求某个区间权值最大值,一般这个权值还与区间长度有关,可以考虑分治求解(虽然这题分治与不分治效率差别并不是太大)
洛谷 P5502 - [JSOI2015]最大公约数(区间 gcd 的性质+分治)的更多相关文章
- 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)
P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...
- 【洛谷2257/BZOJ2820】YY的GCD(数论/莫比乌斯函数)
题目: 洛谷2257 预备知识:莫比乌斯定理(懵逼乌斯定理) \(\mu*1=\epsilon\)(证bu明hui略zheng) 其中(我校学长把\(\epsilon(x)\)叫单位函数但是为什么我没 ...
- 洛谷P1880 石子合并(区间DP)(环形DP)
To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...
- 洛谷 P5469 - [NOI2019] 机器人(区间 dp+拉格朗日插值)
洛谷题面传送门 神仙题,放在 D1T2 可能略难了一点( 首先显然对于 P 型机器人而言,将它放在 \(i\) 之后它会走到左边第一个严格 \(>a_i\) 的位置,对于 Q 型机器人而言,将它 ...
- 洛谷P4168 蒲公英 分块处理区间众数模板
题面. 许久以前我还不怎么去机房的时候,一位大佬好像一直在做这道题,他称这道题目为"大分块". 其实这道题目的思想不只可以用于处理区间众数,还可以处理很多区间数值相关问题. 让我们 ...
- 洛谷P1063 能量项链(区间DP)(环形DP)
To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...
- Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)
题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...
- 【洛谷4219】[BJOI2014]大融合(线段树分治)
题目: 洛谷4219 分析: 很明显,查询的是删掉某条边后两端点所在连通块大小的乘积. 有加边和删边,想到LCT.但是我不会用LCT查连通块大小啊.果断弃了 有加边和删边,还跟连通性有关,于是开始yy ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
随机推荐
- netty系列之:使用netty实现支持http2的服务器
目录 简介 基本流程 CleartextHttp2ServerUpgradeHandler Http2ConnectionHandler 总结 简介 上一篇文章中,我们提到了如何在netty中配置TL ...
- Takin Talks·上海 |开源后首场主题研讨会来了,一起解密Takin技术吧!
自 6 月 25 日全球首款生产环境全链路压测平台 Takin 正式开源,短短 13 天时间,Github 主页上 Star 数已超过 730,开发者社群也积累了 1500+粉丝.群内技术研讨氛围 ...
- 痞子衡嵌入式:超级下载算法RT-UFL v1.0在Keil MDK下的使用
痞子衡主导的"学术"项目 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计> v1.0 版发布近 4 个月了,部分客户已经在实际项目开发调试中用上了这个 ...
- LeetCode:数组专题
数组专题 有关数组的一些 leetcode 题,在此做一些记录,不然没几天就忘光光了 二分查找 双指针 滑动窗口 前缀和/差分数组 二分查找 本文内容摘录自公众号labuladong中有关二分查找的文 ...
- Allegro如何测量距离,测距工具的使用
http://www.allegro-skill.com/thread-2480-1-1.html
- 21.6.25 test
\(NOI\) 模拟赛 \(T1\) 是树+位运算+dp+优化 打了 \(O(n^2)\) 的暴力dp,只拿到了35分,算了一下参赛的,人均65,中位数60.也能看出一些问题,对于一些模糊的猜测应该尝 ...
- SVN查看项目修改记录及修改内容
工具/原料 svn 一,查看修改记录 1 选择要查看的文件夹,打开之后在空白的地方右键. 2 选择svn里面的"查看日志".show_Log 3 在弹出的日志框里,可以看到,你可以 ...
- Python 调用上级目录的文件
程序结构如下: – src |-- mod1.py |-- lib | |-- mod2.py |-- sub | |-- test.py 具体代码如下: 在test.py里调用mod1 mod2 i ...
- cf17B Hierarchy(额,,,水)
题意: Nick's company employed n people. Now Nick needs to build a tree hierarchy of «supervisor-surbod ...
- scrapy 的response 的相关属性
Scrapy中response介绍.属性以及内容提取 解析response parse()方法的参数 response 是start_urls里面的链接爬取后的结果.所以在parse()方法中,我 ...