Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimzize("Ofast,no-stack-protector")
- #include<bits/stdc++.h>
- //#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;
- typedef pair<int,int> pii;
- void debug(){
- cout<<"\n";
- }
- template <class T,class ... U >
- void debug(T a, U ... b){
- cout<<a<<" ",debug(b...);
- }
- const int N=1e6+7;
- const int INF=1e8;
- vector<int> v[N];
- int dp[N][2];
- int dp2[N][2];
- int s[N];
- bool vis[N];
- bool cycle[N];
- bool deg[N];
- vector<vector<int> > c;
- void findcycle(int x){
- int t=s[x];
- vis[x]=true;
- while(x!=t){
- x=s[x];
- t=s[s[t]];
- vis[x]=vis[t]=true;
- }
- t=s[t];
- if(cycle[x]) return ;
- cycle[x]=true;
- vis[x]=true;
- c.eb();
- c.back().eb(x);
- while(t!=x){
- cycle[t]=true;
- vis[t]=true;
- c.back().eb(t);
- t=s[t];
- }
- }
- void dfs(int x){
- dp[x][0]=0;
- dp[x][1]=1;
- int cost=INF;
- for(int i:v[x]){
- dfs(i);
- dp[x][0]+=max(dp[i][1],dp[i][0]);
- dp[x][1]+=max(dp[i][1],dp[i][0]);
- cost=min(cost,max(dp[i][1]-dp[i][0],0));
- }
- dp[x][1]-=cost;
- }
- int solve(vector<int>&k){
- 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);
- 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;
- rep(i,1,n){
- cin>>s[i];
- deg[s[i]]=true;
- }
- rep(i,1,n){
- if(!deg[i]&&!vis[i]){
- //debug("f",i);
- findcycle(i);
- }
- }
- rep(i,1,n){
- if(!vis[i]){
- //debug("f2",i);
- findcycle(i);
- }
- }
- rep(i,1,n){
- if(!cycle[i]||!cycle[s[i]]) {
- v[s[i]].eb(i);
- }
- }
- int ans=0;
- rep(i,1,n){
- if(cycle[i]){
- dfs(i);
- assert(dp[i][0]+1>=dp[i][1]);
- // debug(i,dp[i][0],dp[i][1]);
- }
- }
- for(vector<int>&v2:c){
- // debug("v2");for(int i:v2) cout<<i<<" ";cout<<"\n";
- int slv=solve(v2);
- ans+=slv;
- }
- cout<<ans<<"\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement