Submission #91151

# Submission time Handle Problem Language Result Execution time Memory
91151 2018-12-26T12:06:30 Z popovicirobert Hard route (IZhO17_road) C++14
0 / 100
21 ms 24192 KB
#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define ld long double
// 217
// 44

using namespace std;

const int MAXN = (int) 5e5;

vector <int> g[MAXN + 1];
pair <int, int> down[MAXN + 1], up[MAXN + 1];

pair <ll, ll> ans = {0, 1};

inline void update(pair <int, int> &a, pair <int, int> b) {
    if(b.second == 0) {
        return ;
    }
    if(a.first < b.first) {
        a = b;
    }
    else if(a.first == b.first) {
        a.second += b.second;
    }
}

inline void update(pair <int, ll> &a, pair <int, ll> b) {
    if(b.second == 0) {
        return ;
    }
    if(a.first < b.first) {
        a = b;
    }
    else if(a.first == b.first) {
        a.second += b.second;
    }
}

inline void update(pair <ll, ll> &a, pair <ll, ll> b) {
    if(b.second == 0) {
        return ;
    }
    if(a.first < b.first) {
        a = b;
    }
    else if(a.first == b.first) {
        a.second += b.second;
    }
}

void dfs_down(int nod, int par) {
    down[nod] = {0, 1};
    for(auto it : g[nod]) {
        if(it != par) {
            dfs_down(it, nod);
            update(down[nod], {down[it].first + 1, down[it].second});
        }
    }
}


void dfs_up(int nod, int par) {
    int sz = g[nod].size();
    vector < pair <int, int> > pref(sz), suff(sz);
    for(int i = 0; i < sz; i++) {
        int it = g[nod][i];
        if(i > 0) {
            pref[i] = pref[i - 1];
        }
        if(it == par) {
            continue;
        }
        update(pref[i], {down[it].first + 2, down[it].second});
    }
    for(int i = sz - 1; i >= 0; i--) {
        int it = g[nod][i];
        if(i < sz - 1) {
            suff[i] = suff[i + 1];
        }
        if(it == par) {
            continue;
        }
        update(suff[i], {down[it].first + 2, down[it].second});
    }
    for(int i = 0; i < sz; i++) {
        int it = g[nod][i];
        if(it != par) {
            update(up[it], {up[nod].first + 1, up[nod].second});
            if(i > 0) {
                update(up[it], pref[i - 1]);
            }
            if(i < sz - 1) {
                update(up[it], suff[i + 1]);
            }
            dfs_up(it, nod);
        }
    }
}

struct Data {
    int mx1, cnt1, nr1;
    ll s1;
    int mx2, cnt2, nr2;
    ll s2;
    // de scos nr2 si s2
};

inline pair <int, ll> combine(Data a, Data b) {
    pair <int, ll> ans = {0, 0};
    if(a.nr1 > 1) {
        update(ans, {2 * a.mx1, (1LL * a.cnt1 * a.cnt1 - a.s1) / 2});
    }
    if(b.nr1 > 1) {
        update(ans, {2 * b.mx1, (1LL * b.cnt1 * b.cnt1 - b.s1) / 2});
    }
    update(ans, {a.mx1 + b.mx1, 1LL * a.cnt1 * b.cnt1});
    update(ans, {a.mx1 + a.mx2, 1LL * a.cnt1 * a.cnt2});
    update(ans, {b.mx1 + b.mx2, 1LL * b.cnt1 * b.cnt2});
    return ans;
}

void solve(int nod, int par) {
    int sz = g[nod].size();
    vector <Data> pref(sz), suff(sz);
    for(int i = 0; i < sz; i++) {
        int it = g[nod][i];
        if(i > 0) {
            pref[i] = pref[i - 1];
        }
        if(it == par) {
            continue;
        }
        if(pref[i].mx1 < down[it].first + 1) {
            pref[i].mx2 = pref[i].mx1, pref[i].cnt2 = pref[i].cnt1, pref[i].nr2 = pref[i].nr1, pref[i].s2 = pref[i].s1;
            pref[i].mx1 = down[it].first + 1, pref[i].cnt1 = down[it].second, pref[i].nr1 = 1, pref[i].s1 = 1LL * down[it].second * down[it].second;
        }
        else if(pref[i].mx1 == down[it].first + 1) {
            pref[i].cnt1 += down[it].second, pref[i].nr1++, pref[i].s1 += 1LL * down[it].second * down[it].second;
        }
        else if(pref[i].mx2 < down[it].first + 1) {
            pref[i].mx2 = down[it].first + 1, pref[i].cnt2 = down[it].second, pref[i].nr2 = 1, pref[i].s2 = 1LL * down[it].second * down[it].second;
        }
        else if(pref[i].mx2 == down[it].first + 1) {
            pref[i].cnt2 += down[it].second, pref[i].nr2++, pref[i].s2 += 1LL * down[it].second * down[it].second;
        }
    }
    for(int i = sz - 1; i >= 0; i--) {
        int it = g[nod][i];
        if(i < sz - 1) {
            suff[i] = suff[i + 1];
        }
        if(it == par) {
            continue;
        }
        if(suff[i].mx1 < down[it].first + 1) {
            suff[i].mx2 = suff[i].mx1, suff[i].cnt2 = suff[i].cnt1, suff[i].nr2 = suff[i].nr1, suff[i].s2 = suff[i].s1;
            suff[i].mx1 = down[it].first + 1, suff[i].cnt1 = down[it].second, suff[i].nr1 = 1, suff[i].s1 = 1LL * down[it].second * down[it].second;
        }
        else if(suff[i].mx1 == down[it].first + 1) {
            suff[i].cnt1 += down[it].second, suff[i].nr1++, suff[i].s1 += 1LL * down[it].second * down[it].second;
        }
        else if(suff[i].mx2 < down[it].first + 1) {
            suff[i].mx2 = down[it].first + 1, suff[i].cnt2 = down[it].second, suff[i].nr2 = 1, suff[i].s2 = 1LL * down[it].second * down[it].second;
        }
        else if(suff[i].mx2 == down[it].first + 1) {
            suff[i].cnt2 += down[it].second, suff[i].nr2++, suff[i].s2 += 1LL * down[it].second * down[it].second;
        }
    }
    pair <ll, ll> cur = combine(suff[0], {0, 0, 0, 0, 0, 0, 0, 0});
    update(ans, {cur.first * up[nod].first, cur.second});
    for(int i = 0; i < sz; i++) {
        int it = g[nod][i];
        if(it != par) {
            solve(it, nod);
            cur = {0, 0};
            if(i == 0) {
                cur = combine(suff[i + 1], {0, 0, 0, 0, 0, 0, 0, 0});
            }
            else if(i == sz - 1) {
                cur = combine(pref[i - 1], {0, 0, 0, 0, 0, 0, 0, 0});
            }
            else {
                cur = combine(pref[i - 1], suff[i + 1]);
            }
            update(ans, {cur.first * (down[it].first + 1), cur.second});
        }
    }
}

int main() {
    //ifstream cin("A.in");
    //ofstream cout("A.out");
    int i, n;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n;
    for(i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int root;
    for(i = 1; i <= n; i++) {
        if(g[i].size() > 1) {
            root = i;
            break;
        }
    }
    dfs_down(root, 0);
    up[root] = {-MAXN, 0};
    dfs_up(root, 0);
    solve(root, 0);
    cout << ans.first << " " << ans.second;
    //cin.close();
    //cout.close();
    return 0;
}

Compilation message

road.cpp: In function 'int main()':
road.cpp:206:9: warning: 'root' may be used uninitialized in this function [-Wmaybe-uninitialized]
     int root;
         ^~~~
# Verdict Execution time Memory Grader output
1 Correct 12 ms 12152 KB Output is correct
2 Correct 10 ms 12288 KB Output is correct
3 Correct 10 ms 12288 KB Output is correct
4 Correct 10 ms 12288 KB Output is correct
5 Correct 10 ms 12348 KB Output is correct
6 Runtime error 21 ms 24192 KB Execution killed with signal 11 (could be triggered by violating memory limits)
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 12 ms 12152 KB Output is correct
2 Correct 10 ms 12288 KB Output is correct
3 Correct 10 ms 12288 KB Output is correct
4 Correct 10 ms 12288 KB Output is correct
5 Correct 10 ms 12348 KB Output is correct
6 Runtime error 21 ms 24192 KB Execution killed with signal 11 (could be triggered by violating memory limits)
7 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 12 ms 12152 KB Output is correct
2 Correct 10 ms 12288 KB Output is correct
3 Correct 10 ms 12288 KB Output is correct
4 Correct 10 ms 12288 KB Output is correct
5 Correct 10 ms 12348 KB Output is correct
6 Runtime error 21 ms 24192 KB Execution killed with signal 11 (could be triggered by violating memory limits)
7 Halted 0 ms 0 KB -