solution-cf359d

较为简单的一道数据结构题。

思路

首先考虑暴力。对于每一个序列中的数 $a_i$ 暴力向后和向前拓展,虽然在随机数据跑得飞快,但是最坏可以被卡到 $O(n^2)$。

稍微观察一下题面,发现是求区间 $\operatorname{gcd}$ 。回想一下 $\operatorname{gcd}$ 的性质,我们发现 $\operatorname{gcd}$ 满足结合律。满足结合律就可以考虑使用一些数据结构进行优化。这里我们可以使用线段树之类的数据结构。考虑对于每个可能长度都进行一次枚举,再 $\log(n)$ 求出区间 $\operatorname{gcd}$ ,区间最小值,如果区间 $\operatorname{gcd}$ 等于区间最小值,那这个区间就是可行的。复杂度 $O(n \log n)$。

可惜以上复杂度并不能够顺利通过此题,但是我们稍加思考,即可发现可行的区间长度满足单调性,考虑使用二分答案进行优化,即可将复杂度降至 $O(n \log^2 n)$。

代码

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long 
const int maxn = 500000+5;
int gcd(int a, int b){
    if(b == 0){
        return a;
    }
    return gcd(b,a%b);
}

int n;
int a[maxn], f[maxn][25], f2[maxn][25];

void init(){
    for(int i = 1; i <= n; i++) f[i][0] = a[i];
    for(int j = 1; j <= 25; j++)
    for(int i = 1; i +(1 <<j) -1 <= n; ++i){
        f[i][j] = min(f[i][j-1], f[i+(1<<(j-1))][j-1]);
    } 
}

void init2(){
    for(int i = 1; i <= n; i++) f2[i][0] = a[i];
    for(int j = 1; j <= 25; j++)
    for(int i = 1; i +(1 <<j) -1 <= n; ++i){
        f2[i][j] = gcd(f2[i][j-1], f2[i+(1<<(j-1))][j-1]);
    } 
}
int cnt;
int ans[500005];

int q(int l, int r){
    int k = log2(r-l+1);
    return min(f[l][k], f[r-(1<<k)+1][k]);
}

int q2(int l, int r){
    int k = log2(r-l+1);
    return gcd(f2[l][k], f2[r-(1<<k)+1][k]);
}

bool check(int x){
    for(int i = 1; i <= n-x+1; i++){
        if(q2(i, i+x-1) ==  q(i, i+x-1)){
            ans[++cnt] = i;
        }
    }
    if(cnt) return 1;
    return 0;
}

signed main()
{   ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for(int i = 1; i <= n; i++) cin>>a[i];
    memset(f, 0x3f, sizeof(f));
    init();
    init2();
    int L = 1, R = n;
    while(L <= R){
        int mid = (L+R)/2;
        if(check(mid)){
            L = mid + 1;
            cnt  = 0;
        }else{
            R = mid-1;
            cnt = 0;
        }
    } 
    check(R);
    cout<<cnt<<' '<<R-1<<endl;
    for(int i = 1; i <= cnt; i++){
        cout<<ans[i]<<' ';
    }
    return 0;
}

相关练习

CF475D

posted @ 2022-07-21 17:08  WRuperD  阅读(1)  评论(0编辑  收藏  举报  来源

本文作者:DIVMonster

本文链接:https://www.cnblogs.com/guangzan/p/12886111.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

这是一条自定义内容

这是一条自定义内容