洛谷题面传送门

学校模拟赛的某道题让我联想到了这道题……

先讲一下我的野鸡做法。

首先考虑分治,对于左右端点都在 \([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 的性质+分治)的更多相关文章

  1. 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)

    P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...

  2. 【洛谷2257/BZOJ2820】YY的GCD(数论/莫比乌斯函数)

    题目: 洛谷2257 预备知识:莫比乌斯定理(懵逼乌斯定理) \(\mu*1=\epsilon\)(证bu明hui略zheng) 其中(我校学长把\(\epsilon(x)\)叫单位函数但是为什么我没 ...

  3. 洛谷P1880 石子合并(区间DP)(环形DP)

    To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...

  4. 洛谷 P5469 - [NOI2019] 机器人(区间 dp+拉格朗日插值)

    洛谷题面传送门 神仙题,放在 D1T2 可能略难了一点( 首先显然对于 P 型机器人而言,将它放在 \(i\) 之后它会走到左边第一个严格 \(>a_i\) 的位置,对于 Q 型机器人而言,将它 ...

  5. 洛谷P4168 蒲公英 分块处理区间众数模板

    题面. 许久以前我还不怎么去机房的时候,一位大佬好像一直在做这道题,他称这道题目为"大分块". 其实这道题目的思想不只可以用于处理区间众数,还可以处理很多区间数值相关问题. 让我们 ...

  6. 洛谷P1063 能量项链(区间DP)(环形DP)

    To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...

  7. Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)

    题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...

  8. 【洛谷4219】[BJOI2014]大融合(线段树分治)

    题目: 洛谷4219 分析: 很明显,查询的是删掉某条边后两端点所在连通块大小的乘积. 有加边和删边,想到LCT.但是我不会用LCT查连通块大小啊.果断弃了 有加边和删边,还跟连通性有关,于是开始yy ...

  9. 题解 洛谷 P3396 【哈希冲突】(根号分治)

    根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...

随机推荐

  1. 【Spring】IoC容器 - 依赖来源

    前言 上一篇文章已经学习了[依赖注入]相关的知识,这里详细的介绍一下[依赖来源]. 依赖来源 我们把依赖来源分为依赖查找的来源和依赖注入的来源分别讨论. 依赖查找的来源 1. Spring BeanD ...

  2. Bubble和BubbleButton气泡框

    from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.lang.builder import Buil ...

  3. JVM:GC Roots

    JVM:GC Roots 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 JVM 垃圾回收的时候如何确定垃圾 什么是垃圾 简单来说就是内存中已经不再被使用的空间就 ...

  4. UltraSoft - DDL Killer - Alpha 项目展示

    团队介绍 CookieLau fmh 王 FUJI LZH DZ Monster PM & 后端 前端 前端 前端 后端 后端 软件介绍 项目简介 项目名称:DDLKiller 项目描述:&q ...

  5. Vue3+Typescript+Node.js实现微信端公众号H5支付(JSAPI v3)教程--各种填坑

    ----微信支付文档,不得不说,挺乱!(吐槽截止) 功能背景 微信公众号中,点击菜单或者扫码,打开公众号中的H5页面,进行支付. 一.技术栈 前端:Vue:3.0.0,typescript:3.9.3 ...

  6. 零基础小白要如何跟好的学习嵌入式Linux

    作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这篇文章来回答一下. 在学习嵌入式Linux之前,肯定要有C语言基础.汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会). C语言要学 ...

  7. 因为一个小小的Integer问题导致阿里一面没过,遗憾!

    面试题:new Integer(112)和Integer.valueOf(112)的区别 面试官考察点猜想 这道题,考察的是对Integer这个对象原理的理解,关于这道题的变体有很多,我们会一一进行分 ...

  8. Python pip 和pip3区别 联系

    python 有python2和python3的区别 那么pip也有pip和pip3的区别 大概是这样的 pip是python的包管理工具,pip和pip3版本不同,都位于Scripts\目录下: 如 ...

  9. cf Make It Nondeterministic (简单贪心)

    有N个人.每个人都有两个名字. 给出这N个人的一个排列.p[1]...p[N]. 现在让每个人挑自己丙个名字中的一个名字.问是否存在一种方案,使得挑出来的N个名字按字典序排完以后正好是p[1]...p ...

  10. 记录 mysql 使用时遇到的问题

    1,linux平台上mysqld和mysql的区别. 首先,mysql数据库是标准的c/s架构,yum安装时注意到了,有mysql和mysql-server包 mysql是客户端的工具,mysqld ...