2021杭电多校赛第七场

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;
}
上一篇:折纸问题


下一篇:分数相加and化简——PAT (Advanced Level) 1081 Rational Sum (20 分)