Codeforces Round #736 (Div. 2). D - Integers Have Friends

原题:D - Integers Have Friends

题意:

给定一个数组,求一个最长子数组满足aimodm=ai+1modm=...=ajmodm(m2)
求其最长长度。

根据同余定理ab(modm)等价于ab可以被m整除。那么还有b[i]=a[i+1]a[i],所以说如果一个子数组同余于m,那么这个子数组的差分数组一定可以被m整除,那么就说明这个子数组有一个最大公约数m,所以我们可用线段树或者st表来维护一下区间的gcd,那么对于求一个区间最大长度用双指针维护即可。

代码

 #include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 2E5 + 10, M = 20;
LL a[N], b[N];
int n;
LL f[N][M];
int l2g[N];

void init() {
    for (int j = 0; j < M; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            if (!j) f[i][j] = b[i];
            else f[i][j] = __gcd(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
        }
    }
}

LL query(int l, int r) {
    int k = l2g[r - l + 1];
    return __gcd(f[l][k], f[r - (1 << k) + 1][k]);
}

int main() {
    int t; scanf("%d", &t);
    l2g[2] = 1;
    for (int i = 3; i <= N; i++) l2g[i] = l2g[i / 2] + 1;
    while (t--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        for (int i = 1; i <= n - 1; i++) b[i] = abs(a[i] - a[i + 1]);
        if (n == 1) {
            cout << 1 << endl;
            continue;
        }

        init();
        
        int res = 0;
        int j = 1;
        for (int i = 1; i <= n - 1; i++) {
            while (j <= i && query(j, i) == 1) j++;
            res = max(res, i - j + 2);
        }

        printf("%d\n", res);
    }

    return 0;
} 
posted @   Xxaj5  阅读(219)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示