洛谷 P3147 262144

传送门:洛谷 P3147 262144
算法分析:
减弱版详见 洛谷 P3146 248
本题为P3146的加强版,数据范围 \(2\leq n \leq 262144\) , 原题数据范围为 \(2\leq n \leq 248\) ,若沿用原方法,会得到 \(O(n^2)\) 的时间复杂度,必定超时
这时,考虑 \(dp[i][j] \in [1,40]\) ,故设 \(f[i][j]\) 为原题 \(O(n^2)\) 的数组, \(dp[i][j]\) 为当前做法,则有 \(f[i][j]=t,dp[t][i]=j\),此时 \(58\times 262144\) 满足要求

最大数 \(58\) 的由来: \(maxL=log_2262144+40=58\)
时间复杂度:\(O(maxL\times maxN)\)


#include<iostream>
#include<cstdio>
using namespace std;
const int maxN=262144,maxL=58;
int n,dp[maxL+1][maxN+1],ans=0,maxT=0;
inline int read();
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        dp[read()][i]=i+1;
    for(int i=2;i<=maxL;i++)
        for(int j=1;j<=n;j++)
        {
            if(!dp[i][j]) dp[i][j]=dp[i-1][dp[i-1][j]];
            if(dp[i][j]) ans=i;
        }
    printf("%d",ans);
    return 0;
}
inline int read()
{
    int num=0,f=1;
    char ch=getchar();
    while((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    if(ch=='-') {f=-1; ch=getchar();}
    while(ch>='0' && ch<='9')
    {
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

猜你喜欢

转载自www.cnblogs.com/ezsyshx/p/10359348.html