답안 #446900

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
446900 2021-07-23T18:01:30 Z JerryLiu06 Regions (IOI09_regions) C++17
100 / 100
4107 ms 30272 KB
#include <bits/stdc++.h>
 
using namespace std;
 
using ll = long long;
using ld = long double;
using db = 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 rsz resize
#define ins insert 
#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)
 
ll cdiv(ll a, ll b) { return a / b + ((a ^ b) > 0 && a % b); }
ll fdiv(ll a, ll b) { return a / b - ((a ^ b) < 0 && a % b); }
 
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
 
template<class T> void remDup(vector<T>& v) { sor(v); v.erase(unique(all(v)), v.end()); }
 
const int MOD = 1e9 + 7;
const int MXN = 2e5 + 10;
const int MXR = 25e3 + 10;
const ll INF = 1e18;

const int BLOCK = 450; int N, R, Q; int reg[MXN]; vi adj[MXN];

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

vi allLarge; int ind[MXR]; int par[BLOCK][MXR], child[BLOCK][MXR];

void DFS(int X) {
    in[X] = timer++; S[reg[X]].pb(X);

    EACH(Y, adj[X]) DFS(Y); out[X] = timer - 1;
}
bool isAnc(int A, int B) { return in[A] <= in[B] && out[B] <= out[A]; }

// Get answer for (A, B), sz[A] > BLOCK, sz[B] <= BLOCK ~ O(N)

void genPar(int X, int large, int cnt) {
    par[ind[large]][reg[X]] += cnt; int nCnt = cnt + (reg[X] == large);

    EACH(Y, adj[X]) genPar(Y, large, nCnt);
}

// Get answer for (A, B), sz[A] <= BLOCK, sz[B] > BLOCK ~ O(N)

int genChild(int X, int large) {
    int sub = (reg[X] == large); EACH(Y, adj[X]) sub += genChild(Y, large);

    child[ind[large]][reg[X]] += sub; return sub;
}

// Get answer for (A, B), sz[A], sz[B] <= BLOCK ~ O(BLOCK)

int getAns(int A, int B) {
    int L = 0, R = 0; int ans = 0; stack<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 (!anc.empty() && !isAnc(anc.top(), S[A][L])) anc.pop(); anc.push(S[A][L]); L++;
        }
        else { while (!anc.empty() && !isAnc(anc.top(), S[B][R])) anc.pop(); ans += sz(anc); R++; }
    }
    return ans;
}

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

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

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

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

    F0R(i, Q) {
        int A, B; cin >> A >> B;

        if (sz(S[A]) <= BLOCK && sz(S[B]) <= BLOCK) { cout << getAns(A, B) << endl; continue; }

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

Compilation message

regions.cpp: In function 'void DFS(int)':
regions.cpp:45:20: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
   45 | #define EACH(a, x) for (auto& a : x)
      |                    ^~~
regions.cpp:69:5: note: in expansion of macro 'EACH'
   69 |     EACH(Y, adj[X]) DFS(Y); out[X] = timer - 1;
      |     ^~~~
regions.cpp:69:29: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
   69 |     EACH(Y, adj[X]) DFS(Y); out[X] = timer - 1;
      |                             ^~~
regions.cpp: In function 'int getAns(int, int)':
regions.cpp:96:13: warning: this 'while' clause does not guard... [-Wmisleading-indentation]
   96 |             while (!anc.empty() && !isAnc(anc.top(), S[A][L])) anc.pop(); anc.push(S[A][L]); L++;
      |             ^~~~~
regions.cpp:96:75: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'while'
   96 |             while (!anc.empty() && !isAnc(anc.top(), S[A][L])) anc.pop(); anc.push(S[A][L]); L++;
      |                                                                           ^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5576 KB Output is correct
2 Correct 4 ms 5576 KB Output is correct
3 Correct 6 ms 5576 KB Output is correct
4 Correct 6 ms 5576 KB Output is correct
5 Correct 13 ms 5576 KB Output is correct
6 Correct 30 ms 5576 KB Output is correct
7 Correct 53 ms 5576 KB Output is correct
8 Correct 45 ms 5704 KB Output is correct
9 Correct 62 ms 6088 KB Output is correct
10 Correct 82 ms 6088 KB Output is correct
11 Correct 119 ms 6344 KB Output is correct
12 Correct 177 ms 6728 KB Output is correct
13 Correct 194 ms 6472 KB Output is correct
14 Correct 243 ms 7012 KB Output is correct
15 Correct 311 ms 9408 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1222 ms 10244 KB Output is correct
2 Correct 1405 ms 8832 KB Output is correct
3 Correct 2295 ms 12348 KB Output is correct
4 Correct 343 ms 6984 KB Output is correct
5 Correct 415 ms 8564 KB Output is correct
6 Correct 885 ms 11952 KB Output is correct
7 Correct 1613 ms 10176 KB Output is correct
8 Correct 1309 ms 23484 KB Output is correct
9 Correct 2517 ms 13892 KB Output is correct
10 Correct 2980 ms 30272 KB Output is correct
11 Correct 4107 ms 13340 KB Output is correct
12 Correct 1215 ms 15316 KB Output is correct
13 Correct 1733 ms 15828 KB Output is correct
14 Correct 2724 ms 18764 KB Output is correct
15 Correct 3217 ms 20640 KB Output is correct
16 Correct 3156 ms 27936 KB Output is correct
17 Correct 3156 ms 29848 KB Output is correct