QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#106841#6396. Puzzle: Kusabiwhatever#WA 40ms11684kbC++144.2kb2023-05-19 14:56:142023-05-19 14:56:16

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-19 14:56:16]
  • 评测
  • 测评结果:WA
  • 用时:40ms
  • 内存:11684kb
  • [2023-05-19 14:56:14]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a, I = b; i <= I; ++i)
#define per(i, a, b) for (int i = a, I = b; i >= I; --i)
using i64 = long long;
using pii = pair<int, int>;
using piii = pair<pii, int>;
template<typename T> void up(T &x, T y) { if (x < y) x = y; }
template<typename T> void down(T &x, T y) { if (x > y) x = y; }

const int P = 998244353;
void add(int &x, int y) { (x += y) >= P && (x -= P); }
int Add(int x, int y) { return (x += y) >= P ? (x - P) : x; }
void sub(int &x, int y) { (x -= y) < 0 && (x += P); }
int Sub(int x, int y) { return (x -= y) < 0 ? (x + P) : x; }
void mul(int &x, int y) { x = 1ll * x * y % P; }
int Mul(int x, int y) { return 1ll * x * y % P; }
int power(int a, int b, int c = 1) {
    for (; b; b >>= 1, mul(a, a))
        if (b & 1) mul(c, a);
    return c;
}

const int N = 100005;
int n, fa[N], dep[N];
vector<int> e[N];
string tp[N];
vector<pii> ans;

bool check(const vector<int> &duan, const vector<int> &chang) {
    int n = duan.size();
    if ((int) chang.size() != n) return false;
    rep(i, 0, n - 1) if (dep[duan[i]] >= dep[chang[i]]) return false;
    return true;
}
bool cmp(int u, int v) { return dep[u] < dep[v]; }

int dfs(int u) {
    vector<int> chang, duan;
    map<int, int> tong;
    e[u].push_back(u);
    for (auto v : e[u]) {
        int x = v;
        if (v != u) {
            dep[v] = dep[u] + 1;
            x = dfs(v);
        }
        if (!x) continue;
        if (tp[x] == "Chang") chang.push_back(x);
        else if (tp[x] == "Duan") duan.push_back(x);
        else if (tp[x] == "Tong") {
            if (tong[dep[x]]) {
                ans.push_back({tong[dep[x]], x});
                tong[dep[x]] = 0;
            } else {
                tong[dep[x]] = x;
            }
        }
    }
    // cerr << "? " << u << endl;
    
    int D = duan.size(), C = chang.size();
    vector<int> odd;
    for (auto [d, u] : tong) if (u) odd.push_back(u);
    if ((int) odd.size() > 1) {
        cout << "NO\n";
        exit(0);
    }
    if ((int) odd.size() == 1) {
        if (!check(duan, chang)) {
            cout << "NO\n";
            exit(0);
        }
        rep(i, 0, min(C, D) - 1) ans.push_back({duan[i], chang[i]});
        return odd[0];
    }
    
    sort(duan.begin(), duan.end(), cmp);
    sort(chang.begin(), chang.end(), cmp);
    if (abs(D - C) > 1) {
        cout << "NO\n";
        exit(0);
    }
    if (D == C) {
        if (!check(duan, chang)) {
            cout << "NO\n";
            exit(0);
        }
        rep(i, 0, min(C, D) - 1) ans.push_back({duan[i], chang[i]});
        return 0;
    }
    int res = -1;
    if (D == C + 1) {
        int l = 0, r = D - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            auto n_duan = duan;
            n_duan.erase(n_duan.begin() + mid);
            if (check(n_duan, chang)) {
                res = duan[mid];
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
    } else {
        int l = 0, r = C - 1;
        while (l <= r) {
            int mid = (l + r) >> 1;
            auto n_chang = chang;
            n_chang.erase(n_chang.begin() + mid);
            if (check(duan, n_chang)) {
                res = chang[mid];
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
    }
    if (res == -1) {
        cout << "NO\n";
        exit(0);
    }
    if (D == C + 1) {
        duan.erase(find(duan.begin(), duan.end(), res));
    } else {
        chang.erase(find(chang.begin(), chang.end(), res));
    }
    rep(i, 0, min(C, D) - 1) ans.push_back({duan[i], chang[i]});
    return res;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);

    cin >> n;
    rep(o, 1, n - 1) {
        int i; cin >> i;
        cin >> fa[i] >> tp[i];
        e[fa[i]].push_back(i);
    }
    // rep(i, 2, n) cerr << i << " " << fa[i] << "\n";

    if (dfs(1)) {
        cout << "NO\n";
        return 0;
    }

    cout << "YES\n";
    for (auto [u, v] : ans) cout << u << " " << v << "\n";

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 5ms
memory: 8936kb

input:

8
2 1 -
3 1 -
4 2 Tong
5 2 Tong
6 3 Duan
7 3 -
8 7 Chang

output:

YES
4 5
6 8

result:

ok Correct.

Test #2:

score: 0
Accepted
time: 0ms
memory: 8900kb

input:

10
2 1 Duan
3 2 Duan
4 2 -
5 4 Chang
6 2 Chang
7 1 Duan
8 6 Tong
9 6 Tong
10 3 Chang

output:

YES
3 10
8 9
2 6
7 5

result:

ok Correct.

Test #3:

score: 0
Accepted
time: 2ms
memory: 8896kb

input:

2
2 1 Tong

output:

NO

result:

ok Correct.

Test #4:

score: -100
Wrong Answer
time: 40ms
memory: 11684kb

input:

100000
2 1 Duan
3 1 Duan
4 3 -
5 4 Duan
6 3 -
7 4 Duan
8 4 -
9 8 -
10 7 Duan
11 9 -
12 7 Duan
13 7 Duan
14 8 Duan
15 13 -
16 10 Duan
17 11 Duan
18 12 -
19 1 Duan
20 5 Duan
21 4 Duan
22 14 Duan
23 16 -
24 22 Duan
25 16 Duan
26 13 -
27 13 -
28 17 -
29 5 Duan
30 22 -
31 23 -
32 9 Duan
33 5 -
34 30 Duan...

output:

NO

result:

wrong answer Jury has answer but participant has not.