区间 (模拟并查集优化)

Posted cancers

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间 (模拟并查集优化)相关的知识,希望对你有一定的参考价值。

问题描述

给出一个序列 a1, ..., an。
定义一个区间 [l,r] 是好的,当且仅当这个区间中存在一个 i,使得 ai 恰好等于 al, al+1, ...,
ar-1, ar 的最大公因数。
求最长的好的区间的长度。

输入

第一行 n,表示序列的长度;
第二行 n 个数 a1,a2,...,an。

输出

输出一行一个数,表示最长的好的区间的长度。

题解

    题解写代码里可能容易懂?

代码

#include <cstdio>
#define ll long long
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
inline ll read()
    ll x=0,f=1;char c=getchar();
    while (c>'9'||c<'0') if (c=='-') f=-1;c=getchar();
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48);c=getchar();
    return x*f;

const int maxn(4e6+5);
ll n,a[maxn],l[maxn],r[maxn],ans;

void init()
    n=read();
    for (int i(1);i<=n;++i) a[i]=read();


inline ll max(ll a,ll b)return a>b?a:b;

int main()
//  file("block");
    init();
    for (int i(1);i<=n;++i) for (l[i]=i;1<l[i]&&a[l[i]-1]%a[i]==0;l[i]=l[l[i]-1]);//向左扩展,满足左一项是右一项的倍数,则扩展,模拟并查集优化
    for (int i(n);i>=1;--i) for (r[i]=i;r[i]<n&&a[r[i]+1]%a[i]==0;r[i]=r[r[i]+1]);//向右扩展,同上
    for (int i(1);i<=n;++i) ans=max(ans,r[i]-l[i]+1);//计算答案:最长区间
    printf("%lld\n",ans);
    return 0;


以上是关于区间 (模拟并查集优化)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构----并查集

数据结构----并查集

NOIP模拟_54测试并查集二进制搜索区间序列类

并查集-解决区间和纠错问题 hdu-3038

Restructuring Company和Almost Union-Find 并查集的区间合并与并查集的删除

P3295 萌萌哒 并查集RMQ联动