牛客网NOIP赛前集训营-提高组(第四场)B区间

牛客网NOIP赛前集训营-提高组(第四场)B区间

题目描述

给出一个序列$ a_1  \dots   a_n$。

定义一个区间 \([l,r]\) 是好的,当且仅当这个区间中存在一个 \(i\),使得 \(a_i\) 恰好等于 \(a_l, a_{l+1} \ \ \dots \ \ a_{r-1}, a_r\) 的最大公因数。

求最长的好的区间的长度。

输入描述:

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

输出描述:

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

乱搞就行,考试的时候睡了一觉就想出来了

\(f[i]\) 表示前面第一个能被\(a[i]\)整除的位置

\(g[i]\) 表示后面第一个能被\(a[i]\)整除的位置

则可以递推

f[1]=1;
for(int i=2;i<=n;++i){
    if(a[i]%a[f[i-1]]==0)f[i]=f[i-1];
    else f[i]=i;
}
g[n]=n;
for(int i=n-1;i;--i){
    if(a[i]%a[g[i+1]]==0)g[i]=g[i+1];
    else g[i]=i;
}

最后在\(f\)\(g\)里面连续的一段取最长的就行了

但是如果有这种数据:

5
10 6 6 6 9

我们写出\(f\)\(g\)

f: 1 2 2 2 5
g: 1 4 4 4 5

发现有重复数字时位置会不一样

扫描二维码关注公众号,回复: 3462077 查看本文章

所以再用两个数组\(l[i]\)\(r[i]\)乱搞一下

for(int i=1;i<=n;++i)
    r[f[i]]=max(r[f[i]],i),
    l[g[i]]=min(l[g[i]],i);
for(int i=1;i<=n;++i)
    r[i]=max(r[i],r[f[i]]),
    l[i]=min(l[i],l[g[i]]);
for(int i=1;i<=n;++i)ans=max(ans,r[i]-l[i]+1);

注意卡读入,用fread或者ios和tie优化都行

然后就没有然后了

可能我的思路比较别致

#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e6+5;
#define int long long 
char getc(){
    static char buf[maxn],*p1=buf,*p2=buf;
    return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,maxn,stdin),p1==p2)? EOF:*p1++;
}
int mian(){
    int s=0,f=1;char ch;
    while(!isdigit(ch=getc()))(ch=='-')&&(f=-1);
    for(s=ch-'0';isdigit(ch=getc());s=s*10+ch-'0');
    return s*f;
}
int a[maxn],n,f[maxn],g[maxn],ans,l[maxn],r[maxn];
signed main(){
    n=mian();
    for(int i=1;i<=n;++i)a[i]=mian(),l[i]=r[i]=i;
    f[1]=1;
    for(int i=2;i<=n;++i){
        if(a[i]%a[f[i-1]]==0)f[i]=f[i-1];
        else f[i]=i;
    }
    g[n]=n;
    for(int i=n-1;i;--i)
        if(a[i]%a[g[i+1]]==0)g[i]=g[i+1];
        else g[i]=i;
    for(int i=1;i<=n;++i)
        r[f[i]]=max(r[f[i]],i),
        l[g[i]]=min(l[g[i]],i);
    for(int i=1;i<=n;++i){
        r[i]=max(r[i],r[f[i]]),
        l[i]=min(l[i],l[g[i]]);
    }
    for(int i=1;i<=n;++i)ans=max(ans,r[i]-l[i]+1);
    cout<<ans<<endl;
    return 0;
}

让我们一起膜拜大佬@olinr

猜你喜欢

转载自www.cnblogs.com/eric-walker/p/9750394.html