Submission #934183

# Submission time Handle Problem Language Result Execution time Memory
934183 2024-02-26T23:18:12 Z bobbilyking Regions (IOI09_regions) C++17
95 / 100
4428 ms 52344 KB
#pragma GCC target ("avx2")
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")

#include<bits/stdc++.h>
#include<math.h>
using namespace std;

typedef int ll;
typedef long double ld;
typedef pair<ll, ll> pl;
typedef vector<ll> vl;
#define FD(i, r, l) for(ll i = r; i > (l); --i)

#define K first
#define V second
#define G(x) ll x; cin >> x;
#define GD(x) ld x; cin >> x;
#define GS(s) string s; cin >> s;
#define EX(x) { cout << x << '\n'; exit(0); }
#define A(a) (a).begin(), (a).end()
#define F(i, l, r) for (ll i = l; i < (r); ++i)

template<typename A, typename B>
A& chmax(A &a, B b) { return a < b ? (a=b): a; }

template<typename A, typename B>
A& chmin(A &a, B b) { return a > b ? (a=b): a; }




const ll NN = 2e5 + 1;
const ll HEAVYTH = 450;
// const ll HEAVYTH = 750;
const ll RR = 2.5e4 + 1;
const ll AMT = RR / HEAVYTH + 6;

ll label[NN], tin[NN], tout[NN];
vl people[RR];
vl adj[NN];

vl dfsorder;
vl heavies;


ll sz[NN];


void dfsinit(ll i) {
    static int time = 0;
    tin[i] = time++;
    dfsorder.push_back(i);
    sort(A(adj[i]), [&](ll a, ll b) {
        return sz[a] > sz[b];
    });
    for (auto x: adj[i]) dfsinit(x);
    tout[i] = time;
}


bool isPar(ll i, ll j) {
    return tin[i] <= tin[j] and tin[j] < tout[i];
}

ll heavyRoot[AMT][RR];

void solveHeavyRoot(ll ask, ll put) {
    // compute number of ask labels on path to root, add to ans 
    vl stk;
    ll cnt = 0;

    for (auto x: dfsorder) {
        while (stk.size() and !isPar(stk.back(), x)) {
            cnt -= label[stk.back()] == ask;
            stk.pop_back();
        }
        cnt += label[x] == ask;
        stk.push_back(x);

        heavyRoot[put][label[x]] += cnt;

    }
}

ll containsHeavy[AMT][RR];

void solveContainsHeavy(ll ask, ll put) {
    // compute number of ask in subtree, then add to answer 
    vl ans(dfsorder.size() + 1);
    FD(i, ll(dfsorder.size()) - 1, -1) {
        ll x = dfsorder[i];
        for (auto y: adj[x]) ans[x] += ans[y];
        ans[x] += label[x] == ask;
        
        containsHeavy[put][label[x]] += ans[x];
    }
}

vl peopleWhenQuerying[RR];

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0);
    
    G(n) G(r) G(q)
    
    cin >> label[1]; people[label[1]].push_back(1);

    vl p(n+1);
    F(i, 2, n+1) {
        G(par) cin >> label[i]; 
        adj[par].push_back(i);
        people[label[i]].push_back(i);

        p[i] = par;
    }

    FD(i, n, 1) sz[p[i]]+= ++sz[i];

    dfsinit(1);

    F(i, 1, r+1) if (people[i].size() >= HEAVYTH) {
        heavies.push_back(i);
    }

    F(i, 0, heavies.size()) {
        solveHeavyRoot(heavies[i], i);
    }

    F(i, 0, heavies.size()) {
        solveContainsHeavy(heavies[i], i);
    }

    F(i, 1, r+1) if (people[i].size() < HEAVYTH) {
        peopleWhenQuerying[i] = people[i];
        for (auto &x: peopleWhenQuerying[i]) x = tin[x];
        sort(A(peopleWhenQuerying[i]));
    }

    // cout << heavies.size() << " vs " << r << endl;

    // exit(0);
    
    while (q--) {
        G(r1) G(r2)
        assert(r1 != r2);
        
        if (people[r1].size() >= HEAVYTH) {
            cout << heavyRoot[lower_bound(A(heavies), r1) - heavies.begin()][r2] << endl;
        } else if (people[r2].size() >= HEAVYTH) {
            cout << containsHeavy[lower_bound(A(heavies), r2) - heavies.begin()][r1] << endl;
        } else {
            ll ans = 0;
            for (auto x: people[r1]) {
                ans += lower_bound(A(peopleWhenQuerying[r2]), tout[x]) - lower_bound(A(peopleWhenQuerying[r2]), tin[x]);
            }
            cout << ans << endl;
        }
    }
}

Compilation message

regions.cpp: In function 'int main()':
regions.cpp:22:37: warning: comparison of integer expressions of different signedness: 'll' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   22 | #define F(i, l, r) for (ll i = l; i < (r); ++i)
      |                                     ^
regions.cpp:126:5: note: in expansion of macro 'F'
  126 |     F(i, 0, heavies.size()) {
      |     ^
regions.cpp:22:37: warning: comparison of integer expressions of different signedness: 'll' {aka 'int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   22 | #define F(i, l, r) for (ll i = l; i < (r); ++i)
      |                                     ^
regions.cpp:130:5: note: in expansion of macro 'F'
  130 |     F(i, 0, heavies.size()) {
      |     ^
# Verdict Execution time Memory Grader output
1 Correct 3 ms 10840 KB Output is correct
2 Correct 3 ms 10840 KB Output is correct
3 Correct 3 ms 10840 KB Output is correct
4 Correct 5 ms 10840 KB Output is correct
5 Correct 6 ms 10840 KB Output is correct
6 Correct 9 ms 10840 KB Output is correct
7 Correct 15 ms 10840 KB Output is correct
8 Correct 20 ms 10840 KB Output is correct
9 Correct 27 ms 11352 KB Output is correct
10 Correct 45 ms 11360 KB Output is correct
11 Correct 75 ms 11628 KB Output is correct
12 Correct 90 ms 12120 KB Output is correct
13 Correct 127 ms 11748 KB Output is correct
14 Correct 227 ms 12208 KB Output is correct
15 Correct 212 ms 15204 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 941 ms 17364 KB Output is correct
2 Correct 1148 ms 16080 KB Output is correct
3 Correct 2017 ms 19484 KB Output is correct
4 Correct 190 ms 12376 KB Output is correct
5 Correct 224 ms 14424 KB Output is correct
6 Correct 381 ms 23676 KB Output is correct
7 Correct 1261 ms 16504 KB Output is correct
8 Runtime error 93 ms 52344 KB Execution killed with signal 11
9 Correct 2016 ms 19480 KB Output is correct
10 Correct 2664 ms 35924 KB Output is correct
11 Correct 4428 ms 19224 KB Output is correct
12 Correct 1113 ms 22676 KB Output is correct
13 Correct 1453 ms 23256 KB Output is correct
14 Correct 1687 ms 26784 KB Output is correct
15 Correct 2682 ms 28120 KB Output is correct
16 Correct 2541 ms 36028 KB Output is correct
17 Correct 2299 ms 37652 KB Output is correct