洛谷 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 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
随机推荐
- Mybatis 二级缓存应用 (21)
[MyBatis 二级缓存] 概述:一级缓存作用域为同一个SqlSession对象,而二级缓存用来解决一级缓存不能夸会话共享,作用范围是namespace级,可以被多个SqlSession共享(只要是 ...
- Unity——自动化代码生成
自动化代码生成 一.前言 由于之前写过关于UI框架的文章,这篇基于之前的基础,添加了自动生成代码的功能: 如果学习过程有困惑可以跳转到之前的文章<Unity--基于UGUI的UI框架>: ...
- TX-LCN分布式事务之LCN模式
什么是LCN模式 LCN模式是TX-LCN分布式事务模式的一种,L-lock-锁定事务单元.C-confirm-确认事务模块状态. notify-通知事务单元 原理 LCN模式是通过Spring AO ...
- Spring Security中配置AccessDeniedHandler没有生效
现象 在 WebSecurityConfigurerAdapter 配置了如下代码: // 自定义未授权和未登录异常 http.exceptionHandling() .accessDeniedHan ...
- BUAA2020软工团队beta得分总表
BUAA2020软工团队beta得分总表 [TOC] 零.团队博客目录及beta阶段各部分博客地址 团队博客 计划与设计博客 测试报告博客 发布声明博客 事后分析博客 敏 杰 开 发♂ https:/ ...
- mongodb的索引操作
在mongodb中,当我们一个集合中的数据量非常大时,比如几百万条数据,如果不使用索引,对数据的查询就会进行全表扫描,这个时候查询的速度就会非常的慢,此时我们就需要为集合建立上索引,从而加快查询的速度 ...
- Unity的Deferred Shading
什么是Deferred Shading Unity自身除了支持前向渲染之外,还支持延迟渲染.Unity的rendering path可以通过Edit/Project Settings中的Graphic ...
- (转)linux下错误的捕获:errno和strerror的使用,以及perror和strerror的区别
经常在调用linux 系统api 的时候会出现一些错误,比方说使用open() write() creat()之类的函数有些时候会返回-1,也就是调用失败,这个时候往往需要知道失败的原因.这个时候使用 ...
- Mybatis3源码加注释后后编译问题
参考:https://mp.weixin.qq.com/s/v0ihaPsuyGufdc_ImEqX8A给mybatis3源码加注释并编译源代码 编译命令: mvn clean mvn install ...
- 1. 处理静态资源 2. controller如何接受请求得参数 3. 如何把controller得数据保存到view. 4. 在controller如何完成重定向到指定路径 5. controller返回json数据
1. 1. 处理静态资源2. controller如何接受请求得参数3. 如何把controller得数据保存到view.4. 在controller如何完成重定向到指定路径5. controller ...