QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#570627#9319. Bull FarmKeeperHihiWA 0ms3644kbC++205.8kb2024-09-17 16:48:342024-09-17 16:48:35

Judging History

你现在查看的是最新测评结果

  • [2024-09-17 16:48:35]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3644kb
  • [2024-09-17 16:48:34]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

void print(vector<vector<int>> s, int n, int m) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cout << s[i][j] << ' ';
        }
        cout << endl;
    }
    cout << endl;
}

void print(vector<vector<int>> &s) {
    for (int i = 0; i < s.size(); i++) {
        for (int j = 0; j < s[0].size(); j++) {
            cout << s[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}

void print(vector<int> &s, int n) {
    for (int i = 1; i<= n; i++) {
        cout << s[i] << " ";
    }
    cout << endl;
}

void print(vector<int> &s) {
    for (int i = 0; i < s.size(); i++) {
        cout << s[i] << " ";
    }
    cout << endl;
}

struct DSU {
    vector<int> f, siz;
    
    DSU() {}
    DSU(int n) {
        init(n);
    }
    
    void init(int n) {
        f.resize(n + 1);
        iota(f.begin(), f.end(), 0);
        siz.assign(n + 1, 1);
    }
    
    int find(int x) {
        while (x != f[x]) {
            x = f[x] = f[f[x]];
        }
        return x;
    }
    
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return false;
        }
        siz[x] += siz[y];
        f[y] = x;
        return true;
    }
    
    int size(int x) {
        return siz[find(x)];
    }
};

int cal(char x, char y) {
    return (x - 48) * 50 + y - 48;
}

void solve() {
    int n, l, q;
    cin >> n >> l >> q;
    vector to(l + 1, vector<int>(n + 1));
    vector inv(l + 1, vector<int>(n + 1));
    vector<int> is_ok(l + 1);
    vector adj(l + 1, DSU(n));
    vector<vector<pair<int, int>>> pos(l + 1);
    for (int i = 1; i <= l; i++) {
        string s;
        cin >> s;
        vector<int> vis(n + 1);
        for (int j = 0, k = 1; j < s.size(); j += 2, k++) {
            to[i][k] = cal(s[j], s[j + 1]);
            inv[i][to[i][k]] = k;
            vis[to[i][k]] = 1;
        }
        int cnt = accumulate(vis.begin() + 1, vis.end(), 0);
        is_ok[i] = cnt == n || cnt == n - 1;
        if (cnt == n) {
            is_ok[i] = 1;
            for (int j = 1; j <= n; j++) {
                adj[i].merge(j, to[i][j]);
            }
        } else if (cnt == n - 1) {
            is_ok[i] = 2;
            int x = 0;
            vis.assign(n + 1, 0);
            for (int j = 1; j <= n; j++) {
                if (vis[to[i][j]]) {
                    x = to[i][j];
                    break;
                }
                vis[to[i][j]] = 1;
            }
            vector<int> a;
            for (int j = 1; j <= n; j++) {
                if (to[i][j] == x) {
                    a.emplace_back(j);
                }
            }
            assert(a.size() == 2);
            // 初始只能在 a[0] 或者 a[1],其结果都是唯一确定的,把对应的几个点 merge 一下就行了

            auto dfs = [&](auto self, int u, int fa, int t) -> void {
                if (vis[u]) {
                    // cout << "edge = " << t << ' ' << fa << endl;
                    pos[i].emplace_back(t, fa);
                    return;
                }
                vis[u] = 1;
                self(self, inv[i][u], u, t);
            };
            vis.assign(n + 1, 0);
            vis[0] = 1;
            dfs(dfs, a[0], a[0], a[0]);
            vis.assign(n + 1, 0);
            vis[0] = 1;
            dfs(dfs, a[1], a[1], a[1]);
            // 注意是单向边!!!
        }
    }
    vector<vector<tuple<int, int, int>>> qry(l + 1);
    vector<int> ans(q);

    // for (int i = 1; i <= l; i++) {
    //     for (int j = 1; j <= n; j++) {
    //         cout << adj[i].find(j) << " \n"[j == n];
    //     }
    // }

    // cout << "to : \n";
    // print(to, l, n);
    // cout << "inv : \n";
    // print(inv, l, n);
    for (int i = 0; i < q; i++) {
        string s;
        cin >> s;
        int a = cal(s[0], s[1]);
        int b = cal(s[2], s[3]);
        int c = cal(s[4], s[5]);
        // cout << a << ' ' << b << ' ' << c << endl;
        qry[c].emplace_back(a, b, i);
        if (c == 0) {
            ans[i] = a == b;
        }
    }
    DSU dsu(n);
    set<pair<int, int>> yes;
    for (int i = 1; i <= l; i++) {
        if (!is_ok[i]) continue;
        if (is_ok[i] == 1) {
            for (int j = 1; j <= n; j++) {
                dsu.merge(adj[i].find(j), j);
            }  
            for (auto [a, b, idx] : qry[i]) {
                ans[idx] = dsu.same(a, b);
                if (yes.count({dsu.find(a), dsu.find(b)})) {
                    ans[idx] = 1;
                }
            }
            continue;
        }
        for (auto t : pos[i]) {
            yes.insert(t);
        }
        set<pair<int, int>> nex;
        for (auto [a, b] : yes) {
            nex.insert({dsu.find(a), dsu.find(b)});
        }
        swap(yes, nex);
        // cout << "i = " << i << endl;
        // for (auto [a, b] : yes) cout << a << ' ' << b << endl;
        // cout << "p : ";
        // for (int i = 1; i <= n; i++) {
        //     cout << dsu.find(i) << " \n"[i == n];
        // }
        for (auto [a, b, idx] : qry[i]) {
            ans[idx] = dsu.same(a, b);
            if (yes.count({dsu.find(a), dsu.find(b)})) {
                ans[idx] = 1;
            }
        }
    }

    for (int i = 0; i < q; i++) {
        cout << ans[i];
    }
    cout << "\n";

}   

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int t = 1;
    cin >> t;

    while (t--) {
        solve();
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3644kb

input:

2
5 2 4
0305040201
0404040404
030300
020500
050102
020501
6 2 4
030603010601
010203060504
030202
060402
050602
060401

output:

1001
0100

result:

wrong answer 1st lines differ - expected: '1011', found: '1001'