思维题。
由于 a 数组是一个 1-n 的排列,因此对于每个 i,必然有这样的线路: i -> a[i] -> a[a[i]] -> ... -> i
所以必然是一个圈,只需要统计每个圈的大小为 x ,所有圈的平方 x2 和即为答案。
时间复杂度:O(n)
如果说存在一个线路 i -> a[i] -> a[a[i]] -> ... -> j,满足 j != i 。
首先 j 必然不会在之前出现过,否则就与 a 数组是一个 1-n 的排列这部分冲突了。
如果 j != i,那么 a[j] 要么等于 i ,要么不等于 i (一句废话)
也就是说无论如何 j 可以继续走到 a[j] ,直到走到一个 a 的值为 i 为止。
所以必然是存在一个线路从 i -> a[i] -> a[a[i]] -> ... -> i
n = int(input())
a = list(map(int, input().split()))
for i in range(n):
    a[i] -= 1
vis = [0] * n
ans = 0
for i in range(n):
    if vis[i]:
        continue
    vis[i] = 1
    c = 1
    j = a[i]
    while j != i:
        vis[j] = 1
        j = a[j]
        c += 1
    ans += c * c
print(ans)
import java.util.*;
class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] nums = new int[n+1];
        for(int i=0;i<n;i++) nums[i+1] = in.nextInt();
        boolean[] visited = new boolean[n+1];
        long ans=0;
        for(int i=1;i<n+1;i++){
            long size = 0;
            int j = nums[i];
            while(!visited[j]){
                visited[j]=true;
                size++;
                j = nums[j];
            }
            ans += size*size;
        }
        System.out.println(ans);
    }
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 +10;
int dp[maxn];
int nx[maxn];
int vis[maxn];
int sz[maxn];
int num;
void dfs(int now)
{
	if(vis[now]) return ;
	vis[now] = 1;
	num++;
	dfs(nx[now]);
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int a;
		scanf("%d",&a);
		nx[i] = a;
		dp[a]++;
		sz[i] = 1;
	}
	queue<int>v;
	for(int i=1;i<=n;i++)
	{
		if(dp[i]==0)
		{
			v.push(i);
		}
	}
	long long ans = n;
	while(!v.empty())
	{
		int now = v.front();
		v.pop();
		ans += sz[now];
		vis[now] = 1;
		int nex = nx[now];
		sz[nex] += sz[now];
		dp[nex]--;
		if(dp[nex]==0)
			v.push(nex);
	}
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
			num = 0;
			dfs(i);
			ans += 1ll*num*(num-1);
		}
	}
	cout<<ans<<endl;
	return 0;
}
        小红有一个长为n的排列,并使用该排列建了一个有向图。
规则为:第i条边从i连向ai,即有向边i−>ai。
小红想知道有多少二元组<p,q>可以满足,从p出发,能够到达q。
第一行一个整数n。
第二行n个整数ai。
q≤n≤105
1≤ai≤n
一个整数,代表二元组的数量。
输入
3
1 3 2
输出
5