CF1547 F. Array Stabilization (GCD version)
题意:
有一个a数组,每次可以把所有的a[i]变为gcd(a[i],a[(i+1)%n])
问最少多少次可以让a数组都变为相同的值
第i次操作相当于把a[i]变为原始的区间[i,(i+k)%n]的gcd
所以题目相当于问最小的k,满足所有的区间[i,(i+k)%n]的gcd都相等
二分k,然后st表就可以了
因为是模意义下的循环区间
所以可以把a数组复制一遍
#include<bits/stdc++.h> using namespace std; #define N 400003 int n,a[N]; int st[N][18]; int l2[N]; int find(int l,int r) { int len; len=l2[r-l+1]; return __gcd(st[l][len],st[r-(1<<len)+1][len]); } bool check(int k) { int g=find(0,k-1); for(int i=1;i<n;++i) if(find(i,i+k-1)!=g) return false; return true; } int main() { int T,l,r,mid,ans; bool tag; for(int i=2;i<N;++i) l2[i]=l2[i>>1]+1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;++i) scanf("%d",&a[i]); tag=false; for(int i=1;i<n && !tag;++i) if(a[i]!=a[i-1]) tag=true; if(!tag) { printf("0\n"); continue; } for(int i=0;i<n;++i) a[n+i]=a[i]; for(int i=0;i<n+n;++i) st[i][0]=__gcd(a[i],a[i+1]); for(int i=1;1<<i<n;++i) for(int j=0;j+(1<<i-1)<n+n;++j) st[j][i]=__gcd(st[j][i-1],st[j+(1<<i-1)][i-1]); l=1; r=n-1; while(l<=r) { mid=l+r>>1; if(check(mid)) { ans=mid; r=mid-1; } else l=mid+1; } printf("%d\n",ans); } }
分类:
分治——二分
, 其他——倍增/st表
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2020-10-02 UVA10325 The Lottery
2020-10-02 CF979C Kuro and Walking Route