The Bovine Shuffle

The Bovine ShuffleThe\ Bovine\ Shuffle

題目鏈接:luogu P4089 / jozj 6661

題目

FJFJ 堅信快樂的牛可以產出更多的牛奶,因此 FJFJ 在牛棚裏安裝了一個巨大的迪斯科球並且打算讓奶牛們學會跳舞。
FJFJ在許多出名的奶牛舞中選擇了一種叫做 Bovine ShuffleBovine\ Shuffle 的舞蹈。這種舞蹈由 FJFJNN 頭奶牛組成。NN頭奶牛以一種順序排成一行,接着表演數次 shuffleshuffle。每次的 shuffleshuffle 會將奶牛重新排列。FJFJ 爲了讓奶牛們更加快樂,讓奶牛們更容易找到重新排列後的位置,他標記了 NN 頭奶牛的位置。在最開始,所有奶牛排成一排,第一頭奶牛會在位置 11 上,第二隻在 22 上,以此類推。
我們用 NN 個正整數 a1a_1,a2a_2,......,ana_n來描述每次的 shuffleshuffleaiai說明了在位置 ii上的奶牛在經過這回合的 shuffleshuffle 之後,會跑到位置 aia_i上。令 FJFJ 倍感非洲的是,即使 iijj 不同,aiai也可能會等於 ajaj!所以可能在一次 shuffleshuffle 後,有多頭奶牛會跑到同一位置上,在這之後這羣奶牛也會一同行動。
作爲一名資深的養牛大戶&坑牛專家的 FJFJ 猛然發現,無論經過多少次的 shuffleshuffle,一直都有 kk 個位置上有奶牛。FJFJ現在要你在 11 秒內幫他得出 kk 的值,否則就賞你 1018 mod 1010^{18}\ mod\ 10 大板!

輸入

第一行包含一個整數,NN
第二行包含 NN個整數,描述題目中的a1a_1 ​ ,a2a_2 ​ ,, ana_n

輸出

一個整數,代表kk

樣例輸入

4
3 2 1 3

樣例輸出

3

思路

這道題其實要求出所有環的長度之和。
至於爲什麼,我們把牛的移動方向看做連箭頭,那麼就變成了一個有向圖。
那麼一個環裏面的牛就會不停的交換位置,不會重疊。但是如果有某個點指向了環的某一個地方,這個點的牛就會和環裏面的牛重疊。
所以我們只要找出不在環裏面的點,然後統計出所有環的長度之和就可以了。

代碼

#include<cstdio>
#include<cstring>

using namespace std;

int n, a, to[1000001], ru[1000001], ans;
bool in[1000001], in2[1000001];

void dfs(int now) {
	in[now] = 1;
	ru[to[now]]--;
	if (!ru[to[now]]) dfs(to[now]);
}

int dfs1(int now) {
	if (in2[now]) return 0;
	in2[now] = 1;
	return 1 + dfs1(to[now]);
}

int main() {
//	freopen("shuffle.in", "r", stdin);
//	freopen("shuffle.out", "w", stdout);
	
	scanf("%d", &n);//讀入
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a);//讀入
		to[i] = a;//連邊
		ru[a]++;//記錄入讀數
	}
	
	for (int i = 1; i <= n; i++)
		if (!ru[i] && !in[i]) dfs(i);//找出不在環內的點
	for (int i = 1; i <= n; i++)
		if (!in2[i] && !in[i]) ans += dfs1(i);//統計在環中的點的數量
	
	printf("%d", ans);//輸出
	
//	fclose(stdin);
//	fclose(stdout);
	
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章