Submission #583843

# Submission time Handle Problem Language Result Execution time Memory
583843 2022-06-26T10:03:28 Z thezomb1e Regions (IOI09_regions) C++17
95 / 100
8000 ms 113316 KB
//thatsramen

#include <bits/stdc++.h>
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define eb emplace_back
#define pb push_back
#define ft first
#define sd second
#define pi pair<int, int>
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define dbg(...) dbg_out(__VA_ARGS__)

using ll = long long;
using ld = long double;
using namespace std;
using namespace __gnu_pbds;

//Constants
const ll INF = 5 * 1e18;
const int IINF = 2 * 1e9;
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
const ll dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const ld PI = 3.14159265359;

//Templates
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) {return os << '(' << p.first << ", " << p.second << ')';}
template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) {os << '['; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << ']';}
void dbg_out() {cerr << endl;}
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << H << ' '; dbg_out(T...); }
template<typename T> void mins(T& x, T y) {x = min(x, y);}
template<typename T> void maxs(T& x, T y) {x = max(x, y);}
template<typename T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename T> using omset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

//order_of_key(k): number of elements strictly less than k
//find_by_order(k): k-th element in the set

void setPrec() {cout << fixed << setprecision(15);}
void unsyncIO() {cin.tie(0)->sync_with_stdio(0);}
void setIn(string s) {freopen(s.c_str(), "r", stdin);}
void setOut(string s) {freopen(s.c_str(), "w", stdout);}
void setIO(string s = "") {
    unsyncIO(); setPrec();
    if(s.size()) setIn(s + ".in"), setOut(s + ".out");
}

// #define TEST_CASES

struct SegmentTree {
    
    vector<vector<int>> tre;
    int sz;
    
    SegmentTree(vector<int> &a) {
        int n = (int) a.size();
        sz = 1;
        while (sz < n) sz *= 2;
        tre.resize(2 * sz);
        build(a, 1, 0, sz);
    }

    vector<int> op(vector<int> &a, vector<int> &b) {
        vector<int> res;
        int n = a.size(), m = b.size();
        int i = 0, j = 0;
        while (i < n || j < m) {
            if (j == m || (i < n && a[i] < b[j])) {
                res.pb(a[i++]);
            } else {
                res.pb(b[j++]);
            }
        }
        return res;
    }

    void rcl(int x) {
        tre[x] = op(tre[2 * x], tre[2 * x + 1]);
    }

    void build(vector<int> &a, int x, int lx, int rx) {
        if (rx - lx == 1) {
            if (lx < a.size()) {
                tre[x] = {a[lx]};
            }
            return;
        }
        int m = (lx + rx) / 2;
        build(a, 2 * x, lx, m);
        build(a, 2 * x + 1, m, rx);
        rcl(x);
    }

    int get(int l, int r, int bb, int x, int lx, int rx) {
        if (rx <= l || lx >= r) {
            return 0;
        }
        if (l <= lx && r >= rx) {
            int lo = 0, hi = (int) tre[x].size() - 1;
            int res = -1;
            while (lo <= hi) {
                int mi = (lo + hi) / 2;
                if (tre[x][mi] <= bb) {
                    res = mi;
                    lo = mi + 1;
                } else {
                    hi = mi - 1;
                }
            }
            return res + 1;
        }
        int m = (lx + rx) / 2;
        int s1 = get(l, r, bb, 2 * x, lx, m);
        int s2 = get(l, r, bb, 2 * x + 1, m, rx);
        return s1 + s2;
    }

    int get(int l, int r, int bb) {
        return get(l, r, bb, 1, 0, sz);
    }
};

const int MAX = 1000 * 1000 * 1000;
const int sq = 410;

void solve() {
    int n, r, q;
    cin >> n >> r >> q;
    vector<vector<int>> e(n + 5);
    vector<int> region(n + 5), cnt(r + 5, 0);
    cin >> region[1];
    for (int i = 2; i <= n; i++) {
        int p; cin >> p;
        e[p].pb(i);
        cin >> region[i];
        cnt[region[i]]++;
    }
    vector<int> fun(r + 5, 0);
    int pp = 1;
    for (int i = 1; i <= r; i++) {
        if (cnt[i] > sq) fun[i] = pp++;
    }
    vector<int> up_cnt(pp + 2, 0);
    vector<vector<int>> pre(pp + 2, vector<int> (n + 5, 0));
    vector<vector<pi>> init(r + 5);
    int time = 0; 
    function<void(int)> dfs = [&](int f) {
        int reg = region[f];
        for (int i = 1; i < pp; i++) {
            if (pre[i][reg] <= MAX)
                pre[i][reg] += up_cnt[i];
        }
        up_cnt[fun[reg]]++;
        pi cur; cur.ft = time++;
        for (int to : e[f]) {
            dfs(to);
        }
        cur.sd = time++;
        init[reg].pb(cur);
        up_cnt[fun[reg]]--;
    };
    dfs(1);
    vector<SegmentTree> sts;
    for (int i = 1; i <= r; i++) {
        sort(all(init[i]));
        vector<int> tru; 
        for (pi x : init[i]) tru.pb(x.sd);
        sts.pb(SegmentTree(tru));
    }
    for (int i = 0; i < q; i++) {
        int r1, r2; 
        cin >> r1 >> r2;
        if (cnt[r1] > sq) {
            cout << pre[fun[r1]][r2] << endl;
        } else {
            int ans = 0;
            if (!init[r2].empty()) {
                for (pi x : init[r1]) {
                    pi val = {x.ft, -IINF};
                    int j = lower_bound(all(init[r2]), val) - init[r2].begin();
                    ans += sts[r2 - 1].get(j, (int) init[r2].size(), x.sd);
                }
            }
            cout << ans << endl;
        }
    }
}

int main() {
    setIO();

    int tt = 1;
    #ifdef TEST_CASES
        cin >> tt;
    #endif

    while (tt--)
        solve();

    return 0;
}

Compilation message

regions.cpp:5: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
    5 | #pragma GCC optimization ("O3")
      | 
regions.cpp:6: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
    6 | #pragma GCC optimization ("unroll-loops")
      | 
regions.cpp: In member function 'void SegmentTree::build(std::vector<int>&, int, int, int)':
regions.cpp:89:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   89 |             if (lx < a.size()) {
      |                 ~~~^~~~~~~~~~
regions.cpp: In function 'void setIn(std::string)':
regions.cpp:47:30: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   47 | void setIn(string s) {freopen(s.c_str(), "r", stdin);}
      |                       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
regions.cpp: In function 'void setOut(std::string)':
regions.cpp:48:31: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   48 | void setOut(string s) {freopen(s.c_str(), "w", stdout);}
      |                        ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 0 ms 208 KB Output is correct
2 Correct 1 ms 208 KB Output is correct
3 Correct 2 ms 208 KB Output is correct
4 Correct 5 ms 336 KB Output is correct
5 Correct 8 ms 336 KB Output is correct
6 Correct 17 ms 464 KB Output is correct
7 Correct 30 ms 592 KB Output is correct
8 Correct 18 ms 720 KB Output is correct
9 Correct 61 ms 1744 KB Output is correct
10 Correct 101 ms 2512 KB Output is correct
11 Correct 193 ms 3664 KB Output is correct
12 Correct 189 ms 5208 KB Output is correct
13 Correct 284 ms 5656 KB Output is correct
14 Correct 515 ms 7616 KB Output is correct
15 Correct 667 ms 13100 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 3676 ms 24848 KB Output is correct
2 Correct 4113 ms 23012 KB Output is correct
3 Correct 5515 ms 27392 KB Output is correct
4 Correct 368 ms 7472 KB Output is correct
5 Correct 545 ms 10768 KB Output is correct
6 Correct 633 ms 24264 KB Output is correct
7 Correct 2358 ms 23268 KB Output is correct
8 Correct 1552 ms 67244 KB Output is correct
9 Correct 3553 ms 38268 KB Output is correct
10 Correct 5827 ms 113316 KB Output is correct
11 Execution timed out 8055 ms 44480 KB Time limit exceeded
12 Correct 2260 ms 45120 KB Output is correct
13 Correct 3724 ms 45804 KB Output is correct
14 Correct 3624 ms 65352 KB Output is correct
15 Correct 6380 ms 54316 KB Output is correct
16 Correct 6411 ms 60348 KB Output is correct
17 Correct 5421 ms 78712 KB Output is correct