AC代码
不难发现,只要知道该点能够跳到的最远点,就能够顺利求出答案。
1 2 3 4 5 for (int i=1 ;i<=n;++i) cout<<upA[upj[i]]<<" " ; cout<<endl;
那问题就变成了怎么求 i 位置能跳到的最远位置
我们使用记忆化搜索
1 2 3 for (ll i=1 ;i<=n;++i) { upj[i]=max (upI[upA[i]-1 ],i); }
upj[i]的初始化是指我们先给upj[i]赋上一个跳一次或者两次(一定往前跳)的值
1 2 3 4 5 6 7 ll dfs (ll x) { if (vis[x]) return upj[x]; vis[x]=true ; upj[x]=dfs (upj[x]); return upj[x]; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <bits/stdc++.h> using namespace std;typedef long long ll;const ll N=static_cast <ll>(5e5 )+10 ;ll n,T,A[N],upI[N],upA[N],upj[N]; bool vis[N];ll dfs (ll x) { if (vis[x]) return upj[x]; vis[x]=true ; upj[x]=dfs (upj[x]); return upj[x]; } int main () { ios::sync_with_stdio (false ); cin.tie (0 );cout.tie (0 ); cin>>T; while (T--) { cin>>n; for (int i=1 ;i<=n;++i) upI[i]=0 ,vis[i]=false ; for (int i=1 ;i<=n;++i) { cin>>A[i]; } for (int i=1 ;i<=n;++i) { upI[A[i]]=i; } ll maxUpi=0 ; for (int i=1 ;i<=n;++i) { maxUpi=max (upI[i],maxUpi); upI[i]=maxUpi; } ll maxA=0 ; for (int i=1 ;i<=n;++i) { maxA=max (maxA,A[i]); upA[i]=maxA; } for (ll i=1 ;i<=n;++i) { upj[i]=max (upI[upA[i]-1 ],i); } for (int i=1 ;i<=n;++i) { if (vis[i]) continue ; upj[i]=dfs (i); } for (int i=1 ;i<=n;++i) cout<<upA[upj[i]]<<" " ; cout<<endl; } return 0 ; }
心路历程(WA,TLE,MLE……)