CF1547 F. Array Stabilization (GCD version)

Problem - 1547F - Codeforces

 

题意:

有一个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);
    }
}
复制代码

 

posted @   TRTTG  阅读(65)  评论(0编辑  收藏  举报
编辑推荐:
· 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
点击右上角即可分享
微信分享提示