Submission #413522

# Submission time Handle Problem Language Result Execution time Memory
413522 2021-05-28T19:56:21 Z JerryLiu06 Regions (IOI09_regions) C++17
100 / 100
4766 ms 32560 KB
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using db = long double;
using str = string;

using pi = pair<int, int>;
using pl = pair<ll, ll>;
using pd = pair<db, db>;

using vi = vector<int>;
using vb = vector<bool>;
using vl = vector<ll>;
using vd = vector<db>;
using vs = vector<str>;
using vpi = vector<pi>;
using vpl = vector<pl>;
using vpd = vector<pd>;

#define mp make_pair
#define f first
#define s second

#define sz(x) (int)(x).size()
#define bg(x) begin(x)
#define all(x) bg(x), end(x)
#define sor(x) sort(all(x))
#define ft front()
#define bk back()
#define pb push_back
#define pf push_front

#define lb lower_bound
#define ub upper_bound

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) FOR(i, 0, a)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)
#define R0F(i, a) ROF(i, 0, a)
#define EACH(a, x) for (auto& a : x)

const int MOD = 1e9 + 7;
const int MXN = 2e5 + 10;
const int MXR = 25010;
const ll INF = 1e18;

const int BLOCK = 450;

int N, R, Q; vi adj[MXN]; int L[MXN]; // L[i] = Region of i

int timer = 1, in[MXN], out[MXN]; vi S[MXR]; // Sorted list of {in, out} for each region

vi large; int child[BLOCK][MXN], par[BLOCK][MXN]; int ind[MXR]; 

// Preorder Traversal ~ O(N)

void DFS(int X, int P) {
    in[X] = timer++; S[L[X]].pb(X);
    
    EACH(Y, adj[X]) if (Y != P) DFS(Y, X); out[X] = timer - 1;
}
bool isAnc(int A, int B) { return in[A] <= in[B] && out[B] <= out[A]; }

// Generate child[][] and par[][] DFS ~ O(N)

int genChild(int X, int P, int reg) {
    int sub = (L[X] == reg); EACH(Y, adj[X]) if (Y != P) sub += genChild(Y, X, reg);

    child[ind[reg]][L[X]] += sub; return sub;
}
void genPar(int X, int P, int reg, int cnt) {
    par[ind[reg]][L[X]] += cnt; cnt += (L[X] == reg);

    EACH(Y, adj[X]) if (Y != P) genPar(Y, X, reg, cnt);
} 

// Get the answer when queried (A, B) ~ O(N)

int genAns(int A, int B) {
    int ans = 0; int L = 0, R = 0; int last = 0; deque<int> anc;

    while (L < sz(S[A]) || R < sz(S[B])) {
        if (L < sz(S[A]) && (R >= sz(S[B]) || in[S[A][L]] < in[S[B][R]])) {
            while (sz(anc) && !isAnc(anc.bk, S[A][L])) anc.pop_back(); anc.pb(S[A][L++]);
        }
        else { while (sz(anc) && !isAnc(anc.bk, S[B][R])) anc.pop_back(); ans += sz(anc); R++; }
    }
    return ans;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);

    cin >> N >> R >> Q >> L[1];

    FOR(i, 2, N + 1) { int A; cin >> A >> L[i]; adj[A].pb(i), adj[i].pb(A); }

    DFS(1, 0); int cur = 0; FOR(i, 1, R + 1) if (sz(S[i]) >= BLOCK) large.pb(i), ind[i] = cur++;

    EACH(i, large) { genChild(1, 0, i); genPar(1, 0, i, 0); }

    F0R(i, Q) {
        int A, B; cin >> A>> B; 
        
        if (sz(S[A]) >= BLOCK) cout << par[ind[A]][B] << endl;

        else if (sz(S[B]) >= BLOCK) cout << child[ind[B]][A] << endl;

        else cout << genAns(A, B) << endl;
    }
}

Compilation message

regions.cpp: In function 'void DFS(int, int)':
regions.cpp:42:20: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
   42 | #define EACH(a, x) for (auto& a : x)
      |                    ^~~
regions.cpp:62:5: note: in expansion of macro 'EACH'
   62 |     EACH(Y, adj[X]) if (Y != P) DFS(Y, X); out[X] = timer - 1;
      |     ^~~~
regions.cpp:62:44: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
   62 |     EACH(Y, adj[X]) if (Y != P) DFS(Y, X); out[X] = timer - 1;
      |                                            ^~~
regions.cpp: In function 'int genAns(int, int)':
regions.cpp:86:13: warning: this 'while' clause does not guard... [-Wmisleading-indentation]
   86 |             while (sz(anc) && !isAnc(anc.bk, S[A][L])) anc.pop_back(); anc.pb(S[A][L++]);
      |             ^~~~~
regions.cpp:86:72: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'
   86 |             while (sz(anc) && !isAnc(anc.bk, S[A][L])) anc.pop_back(); anc.pb(S[A][L++]);
      |                                                                        ^~~
regions.cpp:82:40: warning: unused variable 'last' [-Wunused-variable]
   82 |     int ans = 0; int L = 0, R = 0; int last = 0; deque<int> anc;
      |                                        ^~~~
# Verdict Execution time Memory Grader output
1 Correct 4 ms 5576 KB Output is correct
2 Correct 5 ms 5576 KB Output is correct
3 Correct 7 ms 5576 KB Output is correct
4 Correct 9 ms 5576 KB Output is correct
5 Correct 14 ms 5576 KB Output is correct
6 Correct 22 ms 5700 KB Output is correct
7 Correct 43 ms 5704 KB Output is correct
8 Correct 31 ms 5704 KB Output is correct
9 Correct 30 ms 6088 KB Output is correct
10 Correct 96 ms 6088 KB Output is correct
11 Correct 144 ms 6344 KB Output is correct
12 Correct 188 ms 6728 KB Output is correct
13 Correct 228 ms 6856 KB Output is correct
14 Correct 284 ms 7064 KB Output is correct
15 Correct 293 ms 9416 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1178 ms 10624 KB Output is correct
2 Correct 1579 ms 9928 KB Output is correct
3 Correct 1986 ms 12852 KB Output is correct
4 Correct 367 ms 7240 KB Output is correct
5 Correct 399 ms 8648 KB Output is correct
6 Correct 862 ms 12532 KB Output is correct
7 Correct 1876 ms 10744 KB Output is correct
8 Correct 1387 ms 24832 KB Output is correct
9 Correct 2624 ms 14144 KB Output is correct
10 Correct 3253 ms 32560 KB Output is correct
11 Correct 4766 ms 16292 KB Output is correct
12 Correct 1421 ms 15620 KB Output is correct
13 Correct 2290 ms 16796 KB Output is correct
14 Correct 2738 ms 20056 KB Output is correct
15 Correct 3227 ms 21764 KB Output is correct
16 Correct 3126 ms 30912 KB Output is correct
17 Correct 3290 ms 32448 KB Output is correct