답안 #1044255

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1044255 2024-08-05T08:23:59 Z 정민찬(#11007) Team Coding (EGOI24_teamcoding) C++17
0 / 100
39 ms 98660 KB
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;

const ll B = 200;

struct mySet{
    map<int,int> sub;
    map<pair<int,int>, int> save;
    set<pair<int,int>> ssave;
    deque<int> dq;
    int sz = 0;
};

mySet st[100010];
int id[100010];
vector<int> g[100010];
int dep[100010];
int l[100010];
int par[100010];
vector<pair<int,int>> vec[100010];
map<int,int> cnt[100010];
vector<int> large;
int down[100010];

void Merge(mySet &u, mySet &v, int cdep) {
    while (u.dq.size() < v.dq.size()) u.dq.push_back(0);
    for (auto &[col, d] : v.ssave) {
        if (u.save.find(make_pair(col, d)) != u.save.end()) {
            u.save[make_pair(col, d)] ++;
            continue;
        }
        if (vec[d].size() < B) {
            if (cnt[col][d] > u.dq[d-cdep]) {
                u.sub[col] -= cnt[col][d] - u.dq[d-cdep];
            }
        }
        u.save[{col, d}] = 1;
        u.ssave.insert({col, d});
    }
    
    for (int i=0; i<v.dq.size(); i++) {
        if (vec[cdep + i].size() < B) {
            for (auto &[k, col] : vec[cdep + i]) {
                if (u.ssave.find({col, cdep + i}) != u.ssave.end()) continue;
                if (k > u.dq[i]) {
                    u.sub[col] -= k - u.dq[i];
                }
                else break;
            }
        }
        u.dq[i] += v.dq[i];
        if (vec[cdep + i].size() < B) {
            for (auto &[k, col] : vec[cdep + i]) {
                if (u.ssave.find({col, cdep + i}) != u.ssave.end()) continue;
                if (k > u.dq[i]) {
                    // sub.find()
                    u.sub[col] += k - u.dq[i];
                }
                else break;
            }
        }
    }
    u.sz += v.sz;
}

int pv;
int chk[100010];
int ans[100010];
int tme[100010];
int poss[100010];

int dfs(int x) {
    if (g[x].empty()) {
        id[x] = pv ++;
        st[id[x]].dq.push_back(1);
        st[id[x]].ssave.insert({l[x], dep[x]});
        st[id[x]].save[{l[x], dep[x]}] = 1;
        st[id[x]].sz = 1;
        if (vec[dep[x]].size() < B) {
            for (auto &[i, col] : vec[dep[x]]) {
                if (col == l[x]) continue;
                if (i > 1) {
                    st[id[x]].sub[col] += i - 1;
                }
            }
        }
        if (!chk[l[x]]) {
            poss[x] = 1;
            ans[x] = 1;
        }
        return id[x];
    }
    int cur = -1;
    chk[l[x]] ++;
    for (auto &y : g[x]) {
        int child = dfs(y);
        if (cur == -1) {
            cur = child;
            continue;
        }
        if (st[cur].sz < st[child].sz) swap(cur, child);
        Merge(st[cur], st[child], dep[x] + 1);
    }
    id[x] = cur;
    st[id[x]].dq.push_front(1);
    st[id[x]].ssave.insert({l[x], dep[x]});
    st[id[x]].save[{l[x], dep[x]}] = 1;
    st[id[x]].sz ++;
    if (vec[dep[x]].size() < B) {
        for (auto &[i, col] : vec[dep[x]]) {
            if (col == l[x]) continue;
            if (i > 1) {
                st[id[x]].sub[col] += i - 1;
            }
        }
    }
    chk[l[x]] --;
    for (auto &[i, j] : st[id[x]].sub) {
        cout << i << ' ' << j << '\n';
    }
    if (!chk[l[x]]) {
        poss[x] = 1;
        if (st[id[x]].sub.find(l[x]) != st[id[x]].sub.end())
            ans[x] -= st[id[x]].sub[l[x]];
        auto lit = st[id[x]].ssave.lower_bound(make_pair(l[x], -1));
        auto rit = st[id[x]].ssave.upper_bound(make_pair(l[x], (int)1e9));
        for (auto it=lit; it!=rit; it++) {
            int temp = min(cnt[l[x]][it->second], st[id[x]].dq[it->second - dep[x]]);
            ans[x] += temp - cnt[l[x]][it->second];
        }
        for (auto &d : large) {
            if (d < dep[x] || d > down[x]) continue;
            int temp = min(cnt[l[x]][d], st[id[x]].dq[d - dep[x]]);
            ans[x] += temp;
        }
    }
    
    return id[x];
}

int in[100010], out[100010];
int pv2;

void dfs2(int x) {
    down[x] = dep[x];
    in[x] = ++pv2;
    for (auto &y : g[x]) {
        dep[y] = dep[x] + 1;
        dfs2(y);
        down[x] = max(down[x], down[y]);
    }
    out[x] = pv2;
}

struct Fenwick{
    vector<ll> tree;
    void init(ll n) {
        tree.assign(n+1, 0);
    }
    void upd(ll i, ll v, ll n) {
        while (i <= n) {
            tree[i] += v;
            i += i & -i;
        }
    }
    ll qry(ll i) {
        ll ret = 0;
        while (i) {
            ret += tree[i];
            i -= i & -i;
        }
        return ret;
    }
};

Fenwick seg;

vector<int> t[100010];

int main() {
    ios_base :: sync_with_stdio(false); cin.tie(NULL);
    int N, K;
    cin >> N >> K;
    for (int i=0; i<N; i++) {
        cin >> l[i];
    }
    for (int i=1; i<N; i++) {
        cin >> par[i];
        g[par[i]].push_back(i);
    }
    dep[1] = 0;
    dfs2(0);
    int mxdep = 0;
    for (int i=0; i<N; i++) {
        t[dep[i]].push_back(l[i]);
        mxdep = max(mxdep, dep[i]);
    }
    for (int i=0; i<=mxdep; i++) {
        assert(!t[i].empty());
        sort(t[i].begin(), t[i].end());
        vec[i].push_back({1, t[i][0]});
        for (int j=1; j<t[i].size(); j++) {
            if (t[i][j] != vec[i].back().second) {
                vec[i].push_back({1, t[i][j]});
            }
            else vec[i].back().first ++;
        }
        sort(vec[i].begin(), vec[i].end());
    }
    
    for (int i=0; i<=mxdep; i++) {
        if (vec[i].size() < B) {
            for (auto &[j, col] : vec[i]) {
                cnt[col][i] = j;
            }
        }
        else {
            large.push_back(i);
        }
    }
    
    dfs(0);
    vector<vector<int>> qrs(K);
    for (int i=0; i<N; i++) {
        if (vec[dep[i]].size() < B)
            qrs[l[i]].push_back(i); 
    }
    seg.init(mxdep + 1);
    for (int i=0; i<K; i++) {
        for (auto &j : qrs[i]) {
            seg.upd(dep[j]+1, 1, mxdep+1);
        }
        for (auto &j : qrs[i]) {
            if (poss[j]) {
                ans[j] += seg.qry(down[j]+1) - seg.qry(dep[j]);
            }
        }
        for (auto &j : qrs[i]) {
            seg.upd(dep[j]+1, -1, mxdep+1);
        }
    }
    seg.init(N);
    for (int i=0; i<K; i++) {
        for (auto &j : qrs[i]) {
            seg.upd(in[j], 1, N);
        }
        for (auto &j : qrs[i]) {
            if (poss[j]) {
                tme[j] = ans[j] - (seg.qry(out[j]) - seg.qry(in[j]-1));
            }
        }
        for (auto &j : qrs[i]) {
            seg.upd(in[j], -1, N);
        }
    }
    int mx = -1, mn = 0;
    for (int i=0; i<N; i++) {
        if (poss[i]) {
            if (mx < ans[i]) {
                mx = ans[i];
                mn = tme[i];
            }
            else if (mx == ans[i] && mn > tme[i]) {
                mn = tme[i];
            }
        }
    }
    cout << mx << ' ' << mn << '\n';

    return 0;
}

Compilation message

Main.cpp: In function 'void Merge(mySet&, mySet&, int)':
Main.cpp:45:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::deque<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   45 |     for (int i=0; i<v.dq.size(); i++) {
      |                   ~^~~~~~~~~~~~
Main.cpp: In function 'int main()':
Main.cpp:206:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  206 |         for (int j=1; j<t[i].size(); j++) {
      |                       ~^~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 30 ms 98652 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 34 ms 98588 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 39 ms 98660 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 35 ms 98652 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 30 ms 98652 KB Output isn't correct
2 Halted 0 ms 0 KB -