답안 #427811

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
427811 2021-06-14T23:42:58 Z Odavey Regions (IOI09_regions) C++17
70 / 100
8000 ms 50820 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;
unordered_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 6 ms 6856 KB Output is correct
2 Correct 5 ms 6856 KB Output is correct
3 Correct 6 ms 6856 KB Output is correct
4 Correct 11 ms 6856 KB Output is correct
5 Correct 12 ms 6984 KB Output is correct
6 Correct 35 ms 6984 KB Output is correct
7 Correct 49 ms 6980 KB Output is correct
8 Correct 30 ms 6984 KB Output is correct
9 Correct 80 ms 7752 KB Output is correct
10 Correct 95 ms 7624 KB Output is correct
11 Correct 139 ms 8004 KB Output is correct
12 Correct 224 ms 8772 KB Output is correct
13 Correct 166 ms 8188 KB Output is correct
14 Correct 259 ms 8944 KB Output is correct
15 Correct 293 ms 13120 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1441 ms 13748 KB Output is correct
2 Correct 1287 ms 12028 KB Output is correct
3 Correct 2751 ms 16064 KB Output is correct
4 Correct 337 ms 8944 KB Output is correct
5 Correct 428 ms 11836 KB Output is correct
6 Correct 2153 ms 21956 KB Output is correct
7 Correct 1177 ms 12592 KB Output is correct
8 Correct 1832 ms 22144 KB Output is correct
9 Correct 2484 ms 19896 KB Output is correct
10 Correct 3807 ms 26852 KB Output is correct
11 Correct 4019 ms 18332 KB Output is correct
12 Execution timed out 8103 ms 23380 KB Time limit exceeded
13 Execution timed out 8089 ms 23960 KB Time limit exceeded
14 Execution timed out 8092 ms 30832 KB Time limit exceeded
15 Execution timed out 8007 ms 30116 KB Time limit exceeded
16 Execution timed out 8063 ms 39836 KB Time limit exceeded
17 Execution timed out 8029 ms 50820 KB Time limit exceeded