Submission #1362761

#TimeUsernameProblemLanguageResultExecution timeMemory
1362761mariaclaraThe Ties That Guide Us (CEOI23_incursion)C++20
100 / 100
128 ms7444 KiB
// g++ -std=c++17 grader.cpp incursion.cpp -o incursion

#include<bits/stdc++.h>
#include "incursion.h"

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int MAXN = 45e3+5;
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define mk make_pair 
#define pb push_back
#define fr first 
#define sc second

int sub[MAXN], pai[MAXN], n;
vector<vi> edges;

void calc_sub(int x) {
    sub[x] = 1;

    for(auto viz : edges[x]) {
        if(viz == pai[x]) continue;

        pai[viz] = x;
        calc_sub(viz);
        sub[x] += sub[viz];
    }
}

vi find_centroid(int x) {
    for(auto viz : edges[x]) {
        if(viz == pai[x]) continue;
        if(2*sub[viz] >= n)
            return find_centroid(viz);
    }

    if(sub[x]*2 == n) return {pai[x], x};
    return {x};
}

vi mark(vector<pii> F, int safe) {
    n = sz(F)+1;
    pai[1] = 0;
    edges.clear();
    edges.resize(n+1);

    for(auto [a, b] : F)
        edges[a].pb(b), edges[b].pb(a);

    calc_sub(1);
    vi c = find_centroid(1);
    int m = sz(c)-1;

    pai[c[0]] = c[m];
    pai[c[m]] = c[0];

    calc_sub(c[0]);
    calc_sub(c[m]);

    vi ans(n);
    int ss = safe;

    while(true) {
        ans[safe-1] = 1;
        if(pai[pai[safe]] == safe) break;
        safe = pai[safe];
    }

    //ans[ss-1] = 2;
    return ans;
}

void locate(vector<pii> F, int curr, int ties) {
    n = sz(F)+1;
    pai[1] = 0;
    edges.clear();
    edges.resize(n+1);

    for(auto [a, b] : F)
        edges[a].pb(b), edges[b].pb(a);

    for(int i = 1; i <= n; i++) {
        if(sz(edges[i]) >= 3) sub[0] = sub[-1];
    }

    calc_sub(1);
    vi c = find_centroid(1);
    int m = sz(c)-1;

    pai[c[0]] = c[m];
    pai[c[m]] = c[0];

    calc_sub(c[0]);
    calc_sub(c[m]);

    // a partir daqui ja sabemos os pais de cada um
    // e vamos subir

    while(ties == 0) {
        curr = pai[curr];
        ties = visit(curr);
    }
    // ties = 1, agora descemos

    while(true) {
        if(ties == 2) break;

        vi v;

        for(auto viz : edges[curr])
            if(viz != pai[curr]) v.pb(viz);

        if(v.empty()) break;

        sort(all(v), [](int a, int b){
            if(sub[a] != sub[b]) return sub[a] > sub[b];
            return a > b;
        });

        int new_c = curr;

        for(auto viz : v) {
            ties = visit(viz);

            if(ties != 0) {
                new_c = viz;
                break;
            }

            ties = visit(curr);
        }

        if(new_c == curr) break;
        else curr = new_c;
    }
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...