传送门:洛谷 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;
}
原文:https://www.cnblogs.com/ezsyshx/p/10359348.html