제출 #1339675

#제출 시각아이디문제언어결과실행 시간메모리
1339675hccoder참나무 (IOI23_beechtree)C++20
22 / 100
68 ms20856 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;
        for (int i = 0; i<N; i++){
            set<int> st; 
            int cnt = 0;
            for (int e: g[i]){
                if (e!=0) {
                    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;
                }
            }
        }
        R[0] = f;
        return R;
    }
}

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

// int main(){
//     // int t = 100;
//     // int n = 5;
//     // int u = 0;
//     // while(t--){
//     //     cout<<t<<endl;
//     //     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){
//     //         for (int e: P) cout<<e<<" ";
//     //         cout<<endl;
//     //         for (int e: C) cout<<e<<" ";
//     //         cout<<endl;
//     //         return 0;
//     //     }
//     //     else {
//     //         u++;
//     //     }
//     // }
//     // cout<<u<<endl;
//     vector<int> R1 = beechtree(5, 10, {-1, 0, 1, 1, 0}, {3, 3, 2, 2, 3});
//     vector<int> R2 = brute(5, 10, {-1, 0, 1, 1, 0}, {3, 3, 2, 2, 3});
//     for (int e: R1) cout<<e<<" ";
//     cout<<endl;
//     for (int e: R2) cout<<e<<" ";
// }

컴파일 시 표준 에러 (stderr) 메시지

beechtree.cpp: In function 'std::vector<int> beechtree(int, int, std::vector<int>, std::vector<int>)':
beechtree.cpp:166:1: warning: control reaches end of non-void function [-Wreturn-type]
  166 | }
      | ^
#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...