답안 #763772

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
763772 2023-06-22T20:42:12 Z izanbf Regions (IOI09_regions) C++14
100 / 100
4444 ms 47872 KB
#include <bits/stdc++.h>
using namespace std;

using vi = vector<int>;
using vvi = vector<vi>;

const int BIG = 4000;
vi r, tin, tout, big_id;
vvi adj, tins, touts, by_r;
vector<vector<long long>> dp;
int timer;

void euler(int u, int p) {
    tin[u] = timer++;
    tins[r[u]].push_back(tin[u]);
    for (int v : adj[u]) {
        if (v != p) euler(v, u);
    }
    tout[u] = timer++;
    touts[r[u]].push_back(tout[u]);
}

int count_in_range(const vi& v, int l, int r) {
    if (v.empty()) return 0;
    int i = upper_bound(v.begin(), v.end(), r) - v.begin();
    int j = upper_bound(v.begin(), v.end(), l) - v.begin();
    // cerr << "$$" << 1+rg << " " << l << " " << r << " " << j << " " << i << " " << i - j << endl;
    return i - j;
}

void precompute(int rg, int p, int u) {
    // cerr << "%" << 1+rg << " " << 1+u << endl;
    int rid = big_id[rg];
    // cerr << 1+rg << " RID " << rid << " " << u << endl;
    dp[rid][u] = (r[u] == rg);
    for (int v : adj[u]) {
        if (v != p) {
            precompute(rg, u, v);
            dp[rid][u] += dp[rid][v];
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int N, R, Q;
    cin >> N >> R >> Q;

    r = tin = tout = vi(N);
    big_id = vi(R);
    adj = vvi(N);
    tins = touts = by_r = vvi(R);

    vi p(N, -1);

    cin >> r[0]; --r[0];
    by_r[r[0]].push_back(0);

    for (int i = 1; i < N; ++i) {
        cin >> p[i] >> r[i]; --p[i], --r[i];
        by_r[r[i]].push_back(i);
        adj[i].push_back(p[i]);
        adj[p[i]].push_back(i);
    }

    int bigs = 0;
    for (int rg = 0; rg < R; ++rg) {
        if (by_r[rg].size() >= BIG) big_id[rg] = bigs++;
    }

    // O(N/BIG N)
    dp = vector<vector<long long>>(bigs, vector<long long>(N));
    for (int rg = 0; rg < R; ++rg) {
        if (by_r[rg].size() >= BIG) precompute(rg, 0, 0);
    }

    timer = 1;
    euler(0, 0);

    // for (int x : tins[3-1]) cerr << x << " "; cerr << endl;

    // for (int i = 0; i < N; ++i) {
    //     cerr << 1+i << " " << 1+r[i] << "  " << tin[i] << " " << tout[i] << endl;
    // }

    // for (int i = 1; i < N; ++i) {
    //     cerr << 1+i << "(" << 1+r[i] << ")" 
    //     << " " << 1+p[i] << "(" << 1+r[p[i]] << ")" << endl;
    // }
    // cerr << endl << endl;

    map<pair<int,int>,long long> mem;

    while (Q--) {
        int r1, r2;
        cin >> r1 >> r2; --r1, --r2;
        // cerr << 1+r1 << " " << 1+r2 << endl;
        if (by_r[r1].size() < BIG and by_r[r2].size() >= BIG) { // r1 small r2 big
            // O(Q BIG)
            long long cnt = 0;
            int rid = big_id[r2];
            for (int u : by_r[r1]) {
                cnt += dp[rid][u];
            }
            cout << cnt << endl;
        }
        else {
            // O(Q BIG log N)
            if (not mem.count({r1,r2})) {
                long long cnt = 0;
                for (int u : by_r[r2]) {
                    cnt += count_in_range(tins[r1], 0, tin[u])
                         - count_in_range(touts[r1], 0, tin[u]);
                }
                mem[{r1,r2}] = cnt;
            }
            cout << mem[{r1,r2}] << endl;
        }
    }
}




# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 316 KB Output is correct
2 Correct 1 ms 208 KB Output is correct
3 Correct 1 ms 208 KB Output is correct
4 Correct 4 ms 352 KB Output is correct
5 Correct 9 ms 336 KB Output is correct
6 Correct 11 ms 464 KB Output is correct
7 Correct 30 ms 628 KB Output is correct
8 Correct 34 ms 708 KB Output is correct
9 Correct 52 ms 1368 KB Output is correct
10 Correct 94 ms 1648 KB Output is correct
11 Correct 113 ms 2224 KB Output is correct
12 Correct 135 ms 3120 KB Output is correct
13 Correct 188 ms 3340 KB Output is correct
14 Correct 262 ms 3932 KB Output is correct
15 Correct 309 ms 7352 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1125 ms 11368 KB Output is correct
2 Correct 1538 ms 11060 KB Output is correct
3 Correct 2041 ms 16088 KB Output is correct
4 Correct 320 ms 5076 KB Output is correct
5 Correct 284 ms 7728 KB Output is correct
6 Correct 463 ms 8016 KB Output is correct
7 Correct 589 ms 9200 KB Output is correct
8 Correct 1326 ms 18644 KB Output is correct
9 Correct 2419 ms 25224 KB Output is correct
10 Correct 4297 ms 34208 KB Output is correct
11 Correct 4444 ms 33380 KB Output is correct
12 Correct 1369 ms 25516 KB Output is correct
13 Correct 1747 ms 28660 KB Output is correct
14 Correct 3366 ms 31016 KB Output is correct
15 Correct 3376 ms 38920 KB Output is correct
16 Correct 3091 ms 47872 KB Output is correct
17 Correct 3270 ms 47148 KB Output is correct