2021杭電多校賽第七場
阿新 • • 發佈:2021-08-10
Link with Limit
根據極限的定義我們可以得出如下結論:
\(\bullet\) 題目所給\(f_n(x)\)必成環(包括自環)。
\(\bullet\) 對於屬於當前環的\(x\),它們的極限相同。
那麼我們只需要讓每個\(i\)向\(f[i]\)連邊,求出每個環的平均值比較是否相同即可。
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 5; int adj[MAXN], col[MAXN]; int main(int argc, char *argv[]) { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int T; cin >> T; while (T--) { memset(col, 0, sizeof(col)); int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> adj[i]; } bool f = true; int idx = 0, up = 0, down = 0; // up為分子 // down為分母 // solve用於更新up和down auto solve = [&](int &x, int &y) -> void { if (!up) { up = x; down = y; } if (up * y != down * x) { f = false; } }; for (int i = 1; i <= n && f; ++i) { if (col[i]) continue; ++idx; int u = i; while (!col[u]) { col[u] = idx; u = adj[u]; if (col[u] == idx) { // 下一個點已經訪問過代表出現環 int x = 0, y = 0; // x為當前環的權值 // y為當前環的點數 for (int v = u; ; ) { // 遍歷環 x += adj[v], ++y; v = adj[v]; if (v == u) { solve(x, y); break; } } } } } cout << (f ? "YES" : "NO") << '\n'; } system("pause"); return 0; }