제출 #1339685

#제출 시각아이디문제언어결과실행 시간메모리
1339685hccoder참나무 (IOI23_beechtree)C++20
22 / 100
71 ms20992 KiB
#include "bits/stdc++.h"
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
using namespace std;
using ll = long long;

bool is_path(vector<int> P){
    for (int i = 1; i<P.size(); i++){
        if (P[i]!=i-1) return false;
    }
    return true;
}

bool mx_cnt(vector<int> C, int M){
    vector<int> cnt(M+1);
    for (int e: C) cnt[e]++;
    return *max_element(all(cnt))<=2;
}

bool task3(vector<int> P){
    int N = P.size();
    vector<vector<int>> g(N);
    for (int i = 1; i<N; i++){
        g[P[i]].push_back(i);
        g[i].push_back(P[i]);
    }
    int res = 0;
    auto dfs = [&] (auto&& self, int u, int p, int d) -> void {
        res = max(res, d);
        for (int e: g[u]){
            if (e!=p){
                self(self, e, u, d+1);
            }
        }
    };
    dfs(dfs, 0, 0, 0);
    return res<=2;
}

vector<int> brute(int N, int M, vector<int> P, vector<int> C){
    vector<int> R(N);
    vector<vector<int>> g(N);
    for (int i = 1; i<N; i++){
        g[P[i]].push_back(i);
        g[i].push_back(P[i]);
    }
    vector<vector<int>> sub(N);
    auto dfs = [&] (auto&& self, int u, int p) -> void {
        for (int e: g[u]){
            if (e!=p){
                self(self, e, u);
                for (int x: sub[e]) sub[u].push_back(x);
            }
        }
        sort(all(sub[u]));
        do {
            map<int, int> cnt;
            bool f = true;
            vector<int> vec = sub[u];
            vec.insert(vec.begin(), u);
            for (int i = 1; i<vec.size(); i++){
                int e = vec[i];
                if (P[e]!=vec[cnt[C[e]]]){
                    f = false;
                    break;
                }
                cnt[C[e]]++;
            }
            if (f){
                R[u] = 1;
                break;
            }
        }
        while(next_permutation(all(sub[u])));
        sub[u].push_back(u);
    };
    dfs(dfs, 0, 0);
    return R;
}

vector<int> beechtree(int N, int M, vector<int> P, vector<int> C){
    vector<int> R(N);
    if (N<=8){
        return brute(N, M, P, C);
    }
    else if (is_path(P)){
        set<int> st;
        for (int i = N-1; i>=0; i--){
            if (st.size()<=1) R[i] = 1;
            else break;
            st.insert(C[i]);
        }
        return R;
    }
    else if (mx_cnt(C, M)){
        vector<vector<int>> g(N);
        for (int i = 1; i<N; i++){
            g[P[i]].push_back(i);
            g[i].push_back(P[i]);
        }
        vector<int> height(N);
        auto dfs = [&] (auto&& self, int u, int p) -> void {
            vector<int> ch;
            int cnt = 0;
            set<int> st;
            for (int e: g[u]){
                if (e!=p){
                    self(self, e, u);
                    height[u] = max(height[u], height[e]+1);
                    if (height[e]==1) ch.push_back(e);
                    st.insert(C[e]);
                    cnt++;
                }
            }
            if (height[u]==0) R[u] = 1;
            else if (height[u]==1){
                if (st.size()==cnt) R[u] = 1;
            }
            else if (height[u]==2){
                if (st.size()==cnt && ch.size()==1){
                    int v = ch[0];
                    bool f = true;
                    for (int e: g[v]){
                        if (e!=u){
                            if (st.find(C[e])==st.end()) f = false;
                        }
                    }
                    if (f) R[u] = 1;
                }
            }
        };
        dfs(dfs, 0, 0);
        return R;
    }
    else if (task3(P)){
        vector<vector<int>> g(N);
        for (int i = 1; i<N; i++){
            g[P[i]].push_back(i);
            g[i].push_back(P[i]);
        }
        bool f = true;
        set<int> ss;
        set<int> ss2;
        vector<set<int>> vv;
        for (int i = 0; i<N; i++){
            set<int> st; 
            int cnt = 0;
            for (int e: g[i]){
                if (e!=P[i]) {
                    cnt++;
                    st.insert(C[e]);
                }
            }
            if (st.size()==cnt) R[i] = 1;
            else f = false;
            if (i==0){
                ss = st;
            }
            else {
                for (int e: st){
                    if (ss.find(e)==ss.end()) f = false;
                }
                for (int e: st) ss2.insert(e);
                vv.push_back(st);
            }
        }
        bool gg = false;
        for (set<int> s: vv){
            if (s.size()==ss2.size()) gg = true;
        }
        R[0] = (f && gg);
        return R;
    }
    return {};
}

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

// int main(){
//     int t = 1000;
//     int n = 5;
//     int u = 0;
//     while(t--){
//         vector<int> P(n), C(n);
//         P[0] = -1;
//         for (int i = 1; i<n; i++) P[i] = rng()%i;
//         for (int i = 0; i<n; i++) C[i] = rng()%(n+1)+1;
//         vector<int> R1 = beechtree(n, 10, P, C);
//         vector<int> R2 = brute(n, 10, P, C);
//         if (R1!=R2 && R1.size()){
//             for (int e: P) cout<<e<<" ";
//             cout<<endl;
//             for (int e: C) cout<<e<<" ";
//             cout<<endl;
//             cout<<endl;
//             for (int e: R1) cout<<e<<" ";
//             return 0;
//         }
//         else {
//             u++;
//         }
//     }
//     cout<<u<<endl;
//     // vector<int> R1 = beechtree(5, 10, {-1, 0, 0, 2, 1}, {5, 3, 4, 4, 4});
//     // vector<int> R2 = brute(5, 10, {-1, 0, 0, 2, 1}, {5, 3, 4, 4, 4});
//     // for (int e: R1) cout<<e<<" ";
//     // cout<<endl;
//     // for (int e: R2) cout<<e<<" ";
// }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...