답안 #395500

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
395500 2021-04-28T12:10:43 Z MarcoMeijer Regions (IOI09_regions) C++14
85 / 100
8000 ms 47136 KB
#include <bits/stdc++.h>
using namespace std;
 
// macros
typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<ll, ll> lll;
typedef tuple<int, int, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
typedef vector<lll> vlll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define RE(a,c) REP(a,0,c)
#define RE1(a,c) REP(a,1,c+1)
#define REI(a,b,c) REP(a,b,c+1)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define FOR(a,b) for(auto& a : b)
#define all(a) a.begin(), a.end()
#define INF 1e18
#define EPS 1e-9
#define pb push_back
#define popb pop_back
#define fi first
#define se second
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
 
// input
template<class T> void IN(T& x) {cin >> x;}
template<class H, class... T> void IN(H& h, T&... t) {IN(h); IN(t...); }
 
// output
template<class T1, class T2> void OUT(const pair<T1,T2>& x);
template<class T> void OUT(const vector<T>& x);
template<class T> void OUT(const T& x) {cout << x;}
template<class H, class... T> void OUT(const H& h, const T&... t) {OUT(h); OUT(t...); }
template<class T1, class T2> void OUT(const pair<T1,T2>& x) {OUT(x.fi,' ',x.se);}
template<class T> void OUT(const vector<T>& x) {RE(i,x.size()) OUT(i==0?"":" ",x[i]);}
template<class... T> void OUTL(const T&... t) {OUT(t..., "\n"); }
template<class H> void OUTLS(const H& h) {OUTL(h); }
template<class H, class... T> void OUTLS(const H& h, const T&... t) {OUT(h,' '); OUTLS(t...); }
 
// dp
template<class T> bool ckmin(T&a, T&b) { bool bl = a > b; a = min(a,b); return bl;}
template<class T> bool ckmax(T&a, T&b) { bool bl = a < b; a = max(a,b); return bl;}
 
void program();
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    program();
}
 
 
//===================//
//   begin program   //
//===================//
 
const int MX = 2e5+10;
const int SQ = 450;
const int N = (1<<20);

// input
int n, r, q;
int h[MX];
vi withH[MX];

// tree
vi chl[MX];
int dfsPre[MX], treeBg[MX], treeEd[MX], curDFS=0;
void dfs(int u) {
    treeBg[u] = curDFS;
    dfsPre[u] = curDFS++;
    FOR(v,chl[u]) dfs(v);
    treeEd[u] = curDFS-1;
}

// R > 500
vi dif[MX];

// R <= 500
int m;
int ways[SQ][SQ];
int tot[MX];
int sh[MX], rh[MX];

vii regions[SQ];
void dfs2(int u, int cr, int sm) {
    if(regions[cr].empty()) regions[cr].pb({0,0});
    if(rh[h[u]] == cr)
        sm++, regions[cr].pb({treeBg[u], sm});
    FOR(v,chl[u]) dfs2(v,cr,sm);
    if(rh[h[u]] == cr)
        sm--, regions[cr].pb({treeEd[u]+1, sm});
}

void program() {
    // input
    IN(n,r,q);
    RE1(i,n) {
        if(i != 1) {
            int p; IN(p);
            chl[p].pb(i);
        }
        IN(h[i]);
    }
    dfs(1);
    RE1(i,n) withH[h[i]].pb(i);

    // R >= 500
    RE1(u,n) dif[h[u]].pb(dfsPre[u]);
    RE1(i,r) sort(all(dif[i]));

    // R <= 500
    RE1(i,n) sh[i] = i;
    sort(sh+1,sh+n+1, [](int i, int j) {
        return withH[i].size() > withH[j].size();
    });
    RE1(i,n) rh[sh[i]] = i;
    m = min(r,SQ-2);

    // fill tot
    memset(ways,0,sizeof(ways));
    RE1(j,m) {
        memset(tot,0,sizeof(tot));
        FOR(u,withH[sh[j]]) tot[u] = 1;
        REV(u,1,n+1) FOR(v,chl[u]) tot[u] += tot[v];
        RE1(i,m) FOR(u,withH[sh[i]]) ways[i][j] += tot[u];
    }

    // dfs 2
    RE1(i,m) dfs2(1,i,0);

    // answer queries
    RE(_,q) {
        int r1, r2; IN(r1,r2);
        if(rh[r1] <= m && rh[r2] <= m) {
            OUTL(ways[rh[r1]][rh[r2]]);
            cout.flush();
        } else {
            if(rh[r1] <= m) {
                int res = 0;
                FOR(u,withH[r2]) res += (--upper_bound(all(regions[rh[r1]]),ii{dfsPre[u],1e9}))->se;
                OUTL(res);
                cout.flush();
            } else {
                int res = 0;
                FOR(u,withH[r1]) res += upper_bound(all(dif[r2]),treeEd[u]) - lower_bound(all(dif[r2]),treeBg[u]);
                OUTL(res);
                cout.flush();
            }
        }
    }
}
# 결과 실행 시간 메모리 Grader output
1 Correct 11 ms 15944 KB Output is correct
2 Correct 11 ms 15944 KB Output is correct
3 Correct 14 ms 15944 KB Output is correct
4 Correct 17 ms 15944 KB Output is correct
5 Correct 22 ms 16016 KB Output is correct
6 Correct 58 ms 16108 KB Output is correct
7 Correct 51 ms 16072 KB Output is correct
8 Correct 53 ms 16200 KB Output is correct
9 Correct 103 ms 16832 KB Output is correct
10 Correct 167 ms 16776 KB Output is correct
11 Correct 222 ms 17344 KB Output is correct
12 Correct 341 ms 18108 KB Output is correct
13 Correct 444 ms 17856 KB Output is correct
14 Correct 357 ms 18824 KB Output is correct
15 Correct 387 ms 22848 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1207 ms 23500 KB Output is correct
2 Correct 1474 ms 22088 KB Output is correct
3 Correct 1725 ms 26244 KB Output is correct
4 Correct 671 ms 18548 KB Output is correct
5 Correct 759 ms 21000 KB Output is correct
6 Correct 1401 ms 20236 KB Output is correct
7 Correct 1980 ms 21848 KB Output is correct
8 Correct 2029 ms 29840 KB Output is correct
9 Correct 6049 ms 30096 KB Output is correct
10 Correct 4373 ms 37484 KB Output is correct
11 Execution timed out 8061 ms 30660 KB Time limit exceeded
12 Execution timed out 8100 ms 31224 KB Time limit exceeded
13 Correct 7337 ms 32012 KB Output is correct
14 Execution timed out 8041 ms 32096 KB Time limit exceeded
15 Correct 5993 ms 37848 KB Output is correct
16 Correct 5228 ms 47136 KB Output is correct
17 Correct 4816 ms 45432 KB Output is correct