Codeforces Round #736 D

D. Integers Have Friends

同余问题显然不好考虑其%数是啥 我们考虑不考虑其模数转化一下
我们知道同余既然余数相同 显然可以构造差值序列(和差分不同 这个没有首项 因为我们这个差值就相当于是i和i+1连接的纽带 要是这个差值满足的话i和i+1都会满足)消除余数都为0 然后都是整除m的
就转化成了 区间gcd>1的问题 可以用线段树 st表都可以
但是都要注意边界判断 l=0 r=n-1

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 1000000007;
#define int long long
#define endl '\n'
#define Endl '\n'
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int f[N][20],n,a[N],m;
void init(){
    for(int len=0;len<20;len++){
        for(int i=1;i+(1<<len)-1<=m;i++){
            if(!len)f[i][len]=abs(a[i+1]-a[i]);
            else f[i][len]=__gcd(f[i][len-1],f[i+(1<<(len-1))][len-1]);
        }   //i+1<<len-1的话是包括了i 不用加1
    }
}
int query(int l,int r){
    int len=r-l+1;
    int k=log(len)/log(2);
    return __gcd(f[l][k],f[r-(1<<k)+1][k]); //而r-1<<k是没有包含到r所以要+1
}
bool check(int len){
    for(int i=1;i+len-1<=m;i++){
        if(query(i,i+len-1)>1)return 1;
    }
    return 0;
}
void solve() {
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    m=n-1;
    init();
    int l=0,r=m;
    while(l<r){
        int mid=l+r+1>>1;
        if(check(mid))l=mid;
        else r=mid-1;
    }
    cout<<l+1<<endl;
}
signed main(){
    fast
    int T;cin>>T;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-09-08 13:35  ycllz  阅读(15)  评论(0)    收藏  举报