답안 #427802

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
427802 2021-06-14T23:16:37 Z Odavey Regions (IOI09_regions) C++17
70 / 100
8000 ms 52124 KB
//
// ~oisín~ C++ Template
//

#include                <bits/stdc++.h>
#define MX_N            200005
#define mp              make_pair
#define mod7            1000000007
#define modpi           314159
#define PI              3.141592653589793238
#define pb              push_back
#define FastIO          ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define All(a)          a.begin(),a.end()
#define fi              first
#define se              second
#define ll              long long int
#define ull             unsigned long long int

int kx[8]  =            {+2, +2, -2, -2, +1, +1, -1, -1};
int ky[8]  =            {+1, -1, +1, -1, +2, -2, +2, -2};
int d9x[9] =            {+1, +1, +1, +0, +0, +0, -1, -1, -1};
int d9y[9] =            {+1, +0, -1, +1, +0, -1, +1, +0, -1};
int dx4[4] =            {+0, +0, +1, -1};
int dy4[4] =            {+1, -1, +0, +0};

ll gcd(ull a, ull b){
    return (a==0)?b:gcd(b%a,a);
}

ll lcm(ull a, ull b){
    return a*(b/gcd(a,b));
}

const long long INF = 1e18;

using namespace std;

int N, R, Q;
int H[MX_N], p[MX_N];
vector<int> adj[MX_N], r[25001];
vector<pair<int, bool> > ord;
map<int, int> cache[25001];

void dfs(int at){
    ord.pb({at, 0});
    r[H[at]].pb((int)ord.size()-1);
    for(int to : adj[at]){
        if(p[at] == to){
            continue;
        }
        dfs(to);
    }
    ord.pb({at, 1});
    r[H[at]].pb((int)ord.size()-1);
}

int main(){
    cin >> N >> R >> Q;
    int c = 1000;
//    int c = sqrt(N);
//    int c = 1000000000;
    cin >> H[0];
    --H[0];
    for(int i=1;i<N;++i){
        cin >> p[i] >> H[i];
        --p[i], --H[i];
        adj[p[i]].pb(i);
    }
    dfs(0);

    for(int j=0;j<R;++j){
        if((int)r[j].size() >= c){
            for(int i=0;i<R;++i){
                if(i == j){
                    continue;
                }
                int x = 0, y = 0;
                int cur;
                int cntA = 0, cntB = 0;
                int ans = 0;
                while(true){
                    if(x == (int)r[i].size() && y == (int)r[j].size()){
                        break;
                    }else if(x == (int)r[i].size()){
                        cur = r[j][y];
                        ++y;
                    }else if(y == (int)r[j].size()){
                        cur = r[i][x];
                        ++x;
                    }else{
                        if(r[i][x] < r[j][y]){
                            cur = r[i][x];
                            ++x;
                        }else{
                            cur = r[j][y];
                            ++y;
                        }
                    }
                    auto P = ord[cur];
                    if(H[P.fi] == i){
                        if(P.se == 0){
                            ++cntA;
                        }else{
                            --cntA;
                        }
                    }else{
                        if(P.se == 0){
                            ++cntB;
                            ans += cntA;
                        }else{
                            --cntB;
                        }
                    }
                }
                cache[i][j] = ans;
            }
        }
    }

    for(int i=0;i<R;++i){
        if((int)r[i].size() >= c){
            for(int j=0;j<R;++j){
                if(i == j){
                    continue;
                }
                int x = 0, y = 0;
                int cur;
                int cntA = 0, cntB = 0;
                int ans = 0;
                while(true){
                    if(x == (int)r[i].size() && y == (int)r[j].size()){
                        break;
                    }else if(x == (int)r[i].size()){
                        cur = r[j][y];
                        ++y;
                    }else if(y == (int)r[j].size()){
                        cur = r[i][x];
                        ++x;
                    }else{
                        if(r[i][x] < r[j][y]){
                            cur = r[i][x];
                            ++x;
                        }else{
                            cur = r[j][y];
                            ++y;
                        }
                    }
                    auto P = ord[cur];
                    if(H[P.fi] == i){
                        if(P.se == 0){
                            ++cntA;
                        }else{
                            --cntA;
                        }
                    }else{
                        if(P.se == 0){
                            ++cntB;
                            ans += cntA;
                        }else{
                            --cntB;
                        }
                    }
                }
                cache[i][j] = ans;
            }
        }
    }

    while(Q--){
        int r1, r2;
        cin >> r1 >> r2;
        --r1, --r2;
        if((int)r[r1].size() >= c || (int)r[r2].size() >= c){
            cout << cache[r1][r2] << endl;
            cout.flush();
        }else{
            int x = 0, y = 0;
            int cur;
            int cntA = 0, cntB = 0;
            int ans = 0;
            while(true){
                if(x == (int)r[r1].size() && y == (int)r[r2].size()){
                    break;
                }else if(x == (int)r[r1].size()){
                    cur = r[r2][y];
                    ++y;
                }else if(y == (int)r[r2].size()){
                    cur = r[r1][x];
                    ++x;
                }else{
                    if(r[r1][x] < r[r2][y]){
                        cur = r[r1][x];
                        ++x;
                    }else{
                        cur = r[r2][y];
                        ++y;
                    }
                }
                auto P = ord[cur];
                if(H[P.fi] == r1){
                    if(P.se == 0){
                        ++cntA;
                    }else{
                        --cntA;
                    }
                }else{
                    if(P.se == 0){
                        ++cntB;
                        ans += cntA;
                    }else{
                        --cntB;
                    }
                }
            }
            cout << ans << endl;
            cout.flush();
        }
    }
}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 6728 KB Output is correct
2 Correct 4 ms 6728 KB Output is correct
3 Correct 7 ms 6728 KB Output is correct
4 Correct 10 ms 6728 KB Output is correct
5 Correct 17 ms 6728 KB Output is correct
6 Correct 28 ms 6856 KB Output is correct
7 Correct 48 ms 6856 KB Output is correct
8 Correct 31 ms 6856 KB Output is correct
9 Correct 54 ms 7496 KB Output is correct
10 Correct 110 ms 7516 KB Output is correct
11 Correct 133 ms 7724 KB Output is correct
12 Correct 162 ms 8644 KB Output is correct
13 Correct 191 ms 8024 KB Output is correct
14 Correct 188 ms 8760 KB Output is correct
15 Correct 374 ms 12948 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1477 ms 13512 KB Output is correct
2 Correct 1371 ms 11824 KB Output is correct
3 Correct 1872 ms 15944 KB Output is correct
4 Correct 210 ms 8756 KB Output is correct
5 Correct 378 ms 11584 KB Output is correct
6 Correct 2145 ms 22812 KB Output is correct
7 Correct 1434 ms 12340 KB Output is correct
8 Correct 1606 ms 21504 KB Output is correct
9 Correct 2112 ms 19684 KB Output is correct
10 Correct 3245 ms 26672 KB Output is correct
11 Correct 3705 ms 18112 KB Output is correct
12 Execution timed out 8039 ms 22048 KB Time limit exceeded
13 Execution timed out 8026 ms 23024 KB Time limit exceeded
14 Execution timed out 8057 ms 34008 KB Time limit exceeded
15 Execution timed out 8066 ms 28460 KB Time limit exceeded
16 Execution timed out 8042 ms 38056 KB Time limit exceeded
17 Execution timed out 8016 ms 52124 KB Time limit exceeded