题目链接:点击查看

题目大意:给出一个长度为 nnn 的数组 aaa,下标从 000 开始,每次操作分为两个步骤:

  1. 构建出数组 bbb,有 bi=gcd(ai,a(i+1)modn)b_i=gcd(a_i,a_{(i+1)\mod n})bi​=gcd(ai​,a(i+1)modn​)
  2. 用数组 bbb 覆盖数组 aaa

问至少需要操作多少次,才能使得数组 aaa 的每个元素都相等

题目分析:

方便起见,下文中的下标 (i+1)modn(i+1)\mod n(i+1)modn 统一用 i+1i+1i+1 表示

需要分析出:

  1. 操作 000 次,ai=aia_i=a_iai​=ai​
  2. 操作 111 次,ai=gcd(ai,ai+1)a_i=gcd(a_i,a_{i+1})ai​=gcd(ai​,ai+1​)
  3. 操作 222 次,ai=gcd(gcd(ai,ai+1),gcd(ai+1,ai+2))=gcd(ai,ai+1,ai+2)a_i=gcd(gcd(a_i,a_{i+1}),gcd(a_{i+1},a_{i+2}))=gcd(a_i,a_{i+1},a_{i+2})ai​=gcd(gcd(ai​,ai+1​),gcd(ai+1​,ai+2​))=gcd(ai​,ai+1​,ai+2​)
  4. 操作 kkk 次,ai=gcd(ai,ai+1,...,ai+k)a_i=gcd(a_i,a_{i+1},...,a_{i+k})ai​=gcd(ai​,ai+1​,...,ai+k​)

不难看出当 kkk 取 nnn 时,所有的数字都等于 nnn 个数的最大公约数,所以操作次数最多有 nnn 次,最少有 000 次

显然 kkk 具有单调性,所以考虑二分 kkk,现在问题是如何快速去求区间 gcdgcdgcd,这里给出两种方法,第一种就是最简单的线段树,但是如果严格来计算复杂度的话,线段树拆分区间一层 logloglog,gcdgcdgcd 一层 logloglog,所以总的时间复杂度是 nlog3nnlog^3nnlog3n 的,但好像是可以通过本题的?

又因为是静态查询,所以不妨直接打个 STSTST 表,这样可以优化掉一层 logloglog,复杂度是 nlog2nnlog^2nnlog2n 的,但 gcdgcdgcd 的那层 logloglog 好像很小,所以近似于 nlognnlognnlogn 的

循环取模的话,只需要将数组复制一遍就可以了

代码:

// Problem: F. Array Stabilization (GCD version)
// Contest: Codeforces - Codeforces Round #731 (Div. 3)
// URL: https://codeforces.com/contest/1547/problem/F
// Memory Limit: 512 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f;
}
template<typename T>
inline void write(T x)
{if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
int a[N],st[N][20],n;
void ST_build()
{for(int i=1;i<=n<<1;i++)st[i][0]=a[i];for(int i=1;i<=20;i++)for(int j=1;j+(1<<i)-1<=n<<1;j++)st[j][i]=__gcd(st[j][i-1],st[j+(1<<(i-1))][i-1]);
}
int ST_query(int l,int r)
{int k=log2(r-l+1);return __gcd(st[l][k],st[r-(1<<k)+1][k]);
}
bool check(int len) {int mark=ST_query(1,1+len);for(int i=2;i<=n;i++) {if(mark!=ST_query(i,i+len)) {return false;}}return true;
}
int main()
{#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--) {read(n);for(int i=1;i<=n;i++) {read(a[i]);a[i+n]=a[i];}ST_build();int l=0,r=n,ans=-1;while(l<=r) {int mid=(l+r)>>1;if(check(mid)) {r=mid-1;ans=mid;} else {l=mid+1;}}cout<<ans<<endl;}return 0;
}

CodeForces - 1547F Array Stabilization (GCD version)(ST表+二分)相关推荐

  1. CF1547F Array Stabilization (GCD version) st表 + 尺取/二分

    传送门 题意: 思路: 容易发现,我们将所有aaa都除上所有aaa的gcdgcdgcd,实际上就是让你求一个最小的lenlenlen,对于所有iii,gcd(ai,ai+1,...,ai+len−1) ...

  2. 2016 Multi-University Training Contest 1 1004 GCD(ST表+二分)

    GCD 注意观察gcd⁡(al,al+1,...,ar)\gcd(a_{l},a_{l+1},...,a_{r})gcd(al​,al+1​,...,ar​),当lll固定不动的时候,r=l...nr ...

  3. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

  4. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

  5. 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)

    题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...

  6. luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分...

    仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...

  7. Codeforces1579 F. Array Stabilization (AND version)(思维+bfs)

    题意: 解法: 注意:题目的d不一定是n的因子,因此不能直接下标对d取模分组.什么时候a[i]会从1变成0? 一定是a[i]=1且a[i+d]=0的时候, 我们反过来考虑,如果a[i]=0且a[i-d ...

  8. P3564 [POI2014]BAR-Salad Bar(ST表 + 二分)

    P3564 [POI2014]BAR-Salad Bar 给定一个长度为nnn的数组,里面元素只有111跟−1-1−1,问选出一个长度为lenlenlen的区间使得,这个区间的前缀和时刻大于零,后缀和 ...

  9. Codeforces 359D Pair of Numbers | 二分+ST表+gcd

    题面: 给一个序列,求最长的合法区间,合法被定义为这个序列的gcd=区间最小值 输出最长合法区间个数,r-l长度 接下来输出每个合法区间的左端点 题解: 由于区间gcd满足单调性,所以我们可以二分区间 ...

最新文章

  1. ceph bluestore 源码分析:ceph-osd内存查看方式及控制源码分析
  2. 查询linux kafka安装目录,Linux下安装并(单节点)配置启动Kafka
  3. 基于Codis的Redis集群部署
  4. ubuntu 16.10安装mysql_在Ubuntu 16.10安装mysql workbench报未安装软件包 libpng12-0错误的解决方法...
  5. 【MM配置】Pricing 采购定价过程总览
  6. SpringSecurity鉴权流程分析 附源码注释,xdm,一起来看看吧
  7. linux中的和,|和||
  8. printf linux 头文件,Linux C 格式化输出时要注意的问题
  9. 表的插入、更新、删除、合并操作_15_ 按照默认值更新表
  10. PYTHON之路DAY3
  11. C# 类(7) 继承
  12. 通过Nginx配置多域名访问
  13. android layout 层次感,FrameLayout的层次问题
  14. 几个容器网络相关问题的分析和解决总结
  15. 通过造车来了解软件开发模式
  16. 页面修改成套用MasterPage时遇到Invalid postback or callback argument的错误
  17. WinRAR去广告方法,了解一下?
  18. Spring Bean生命周期,好像人的一生。。
  19. WIN7远程桌面连接显示凭据不工作的解决方法
  20. 如何关闭计算机软件更新功能,如何关闭电脑自动更新功能

热门文章

  1. Pod详解-生命周期-概述
  2. NioEventLoop 的实例化过程
  3. 简单异常处理器SimpleMappingExceptionResolver
  4. SpringMVC的请求-获得请求参数-静态资源访问的开启
  5. request获得请求参数
  6. Feign-1 Feign的简介及基础使用
  7. switch注意事项和细节讨论
  8. 生成树生成森林c语言中文网,生成树协议(STP)基本知识及实验(使用eNSP)
  9. JMeter 下载安装教程
  10. tcp与ip协议的区别