Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimzize("O1")
- #include<iostream>
- #include<vector>
- #include<queue>
- //#define int long long
- #define quick ios::sync_with_stdio(0);cin.tie(0);
- #define rep(x,a,b) for(int x=a;x<=b;x++)
- #define repd(x,a,b) for(int x=a;x>=b;x--)
- #define lowbit(x) (x&-x)
- #define sz(x) (int)(x.size())
- #define F first
- #define S second
- #define all(x) x.begin(),x.end()
- #define mp make_pair
- #define eb emplace_back
- using namespace std;
- const int N=1e6+1;
- const int INF=1e8;
- int dp[N][2];
- int cost[N];
- int s[N];
- bool vis[N];
- int solve(int x){
- vector<int> k;
- k.eb(x);
- vis[x]=true;
- for(int i=s[x];i!=x;i=s[i]){
- vis[i]=true;
- k.eb(i);
- }
- if(sz(k)==1){
- return max(dp[k.back()][0],dp[k.back()][1]);
- }
- /*else if(sz(k)==2){
- return max({dp[k[0]][0]+dp[k[1]][0]+1,dp[k[1]][1]+dp[k[2]][1]});
- }*/
- int l=sz(k);
- vector<vector<int> > dp2(l,vector<int>(2));
- dp2[0][0]=dp[k[0]][0];
- dp2[0][1]=dp[k[0]][0]+1;// last not choose
- rep(i,1,l-1){
- int now=k[i];
- dp2[i][0]=max(dp2[i-1][0],dp2[i-1][1])+dp[now][0];
- dp2[i][1]=max(dp2[i-1][0]+max(dp[now][0]+1,dp[now][1]),dp2[i-1][1]+dp[now][1]);
- }
- //last choose:
- int ans=dp2[l-1][0];
- //debug("ans1",dp2[l-1][0]);
- dp2[0][0]=dp[k[0]][0];
- dp2[0][1]=dp[k[0]][1];
- rep(i,1,l-1){
- int now=k[i];
- dp2[i][0]=max(dp2[i-1][0],dp2[i-1][1])+dp[now][0];
- dp2[i][1]=max(dp2[i-1][0]+max(dp[now][1],dp[now][0]+1),dp2[i-1][1]+dp[now][1]);
- }
- ans=max(ans,dp2[l-1][1]);
- //debug("ans2",dp2[l-1][1]);
- return ans;
- }
- signed main(){
- quick
- int n;
- cin>>n;
- vector<int> deg(n+1);
- rep(i,1,n){
- cin>>s[i];
- deg[s[i]]++;
- }
- rep(i,1,n){
- cost[i]=INF;
- }
- int ans=0;
- queue<int> q;
- rep(i,1,n){
- dp[i][0]=0;
- dp[i][1]=1;
- if(!deg[i]){
- q.push(i);
- dp[i][1]=-INF;
- cost[i]=0;
- vis[i]=true;
- }
- }
- while(q.size()){
- int x=q.front();
- q.pop();
- int i=s[x];
- dp[i][1]+=max(dp[x][0],dp[x][1]);
- dp[i][0]+=max(dp[x][0],dp[x][1]);
- cost[i]=min(cost[i],max(dp[x][1]-dp[x][0],0));
- deg[i]--;
- if(!deg[i]){
- dp[i][1]-=cost[i];
- cost[i]=0;
- vis[i]=true;
- q.push(i);
- }
- }
- rep(i,1,n) dp[i][1]-=cost[i];
- deg.clear();
- deg.shrink_to_fit();
- rep(i,1,n){
- if(vis[i]) continue;
- ans+=solve(i);
- }
- cout<<ans<<"\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement