제출 #443143

#제출 시각아이디문제언어결과실행 시간메모리
443143JovanB늑대인간 (IOI18_werewolf)C++17
100 / 100
1184 ms149312 KiB
#include "werewolf.h"
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int MAXN = 200000;

struct Edge{
    int a, b, c;
    bool operator <(const Edge &x){
        return c < x.c;
    }
};

struct DSU{
    int n;
    int par[MAXN+5];
    int label[MAXN+5];
    int sz[MAXN+5];
    DSU(int g){
        n = g;
        for(int i=1; i<=n; i++){
            par[i] = i;
            label[i] = i;
            sz[i] = 1;
        }
    }
    int root(int x){ return (par[x] == x ? x : par[x] = root(par[x])); }
    void povezi(int a, int b, int lab){
        if(sz[a] < sz[b]) swap(a, b);
        label[a] = lab;
        sz[a] += sz[b];
        par[b] = a;
    }
};

const int LOG = 20;

struct PMST{
    int n;
    vector <pair <int, int>> graf[2*MAXN+5];
    int L[2*MAXN+5];
    int R[2*MAXN+5];
    int val[2*MAXN+5];
    int par[2*MAXN+5][LOG+1];
    int niz[MAXN+5];
    int tn = 0;
    void dfs(int v, int p, int w){
        val[p] = w;
        par[v][0] = p;
        for(int j=1; j<=LOG; j++) par[v][j] = par[par[v][j-1]][j-1];
        L[v] = 2*MAXN+5;
        R[v] = 0;
        for(auto c : graf[v]){
            dfs(c.first, v, c.second);
            L[v] = min(L[v], L[c.first]);
            R[v] = max(R[v], R[c.first]);
        }
        if(!graf[v].size()){
            tn++;
            L[v] = R[v] = tn;
            niz[tn] = v;
        }
    }
};

PMST tree1, tree2;

int l1[MAXN+5];
int r1[MAXN+5];
int l2[MAXN+5];
int r2[MAXN+5];
int gde[MAXN+5];

int dizi_max(int v, int lm){
    for(int j=LOG; j>=0; j--) if(tree1.val[tree1.par[v][j]] <= lm) v = tree1.par[v][j];
    return v;
}

int dizi_min(int v, int lm){
    for(int j=LOG; j>=0; j--) if(tree2.val[tree2.par[v][j]] >= lm) v = tree2.par[v][j];
    return v;
}

vector <int> queries[MAXN+5];

int bit[MAXN+5];

void addbit(int x){
    while(x <= MAXN){
        bit[x]++;
        x += x & -x;
    }
}

int getbit(int x){
    int res = 0;
    while(x){
        res += bit[x];
        x -= x & -x;
    }
    return res;
}

std::vector<int> check_validity(int N, std::vector<int> X, std::vector<int> Y, std::vector<int> S, std::vector<int> E, std::vector<int> L, std::vector<int> R) {
    int m = X.size();
    vector <Edge> e1, e2;
    for(int i=0; i<m; i++){
        int a = X[i] + 1;
        int b = Y[i] + 1;
        e1.push_back({a, b, max(a, b)});
        e2.push_back({a, b, min(a, b)});
    }
    sort(e1.begin(), e1.end());
    sort(e2.begin(), e2.end());
    reverse(e2.begin(), e2.end());
    int n = N;
    DSU dsu1(n);
    DSU dsu2(n);
    int lab1 = n;
    int lab2 = n;
    for(auto edge : e1){
        int a = edge.a;
        int b = edge.b;
        int c = edge.c;
        int a1 = dsu1.root(a);
        int b1 = dsu1.root(b);
        if(a1 == b1) continue;
        lab1++;
        tree1.graf[lab1].push_back({dsu1.label[a1], c});
        tree1.graf[lab1].push_back({dsu1.label[b1], c});
        dsu1.povezi(a1, b1, lab1);
    }
    tree1.n = lab1;
    for(auto edge : e2){
        int a = edge.a;
        int b = edge.b;
        int c = edge.c;
        int a1 = dsu2.root(a);
        int b1 = dsu2.root(b);
        if(a1 == b1) continue;
        lab2++;
        tree2.graf[lab2].push_back({dsu2.label[a1], c});
        tree2.graf[lab2].push_back({dsu2.label[b1], c});
        dsu2.povezi(a1, b1, lab2);
    }
    tree2.n = lab2;
    tree1.dfs(lab1, 0, 10*MAXN);
    cout << endl;
    tree2.dfs(lab2, 0, 0);
    vector <int> soln;
    int qrs = S.size();
    for(int i=0; i<qrs; i++) soln.push_back(0);
    for(int i=0; i<qrs; i++){
        swap(S[i], E[i]);
        S[i]++;
        E[i]++;
        L[i]++;
        R[i]++;
        int v = dizi_max(S[i], R[i]);
        l1[i] = tree1.L[v];
        r1[i] = tree1.R[v];
        v = dizi_min(E[i], L[i]);
        l2[i] = tree2.L[v];
        r2[i] = tree2.R[v];
        queries[l2[i]-1].push_back(-(i+1));
        queries[r2[i]].push_back(i+1);
    }
    for(int i=1; i<=n; i++){
        gde[tree1.niz[i]] = i;
    }
    for(int i=1; i<=n; i++){
        tree1.niz[i] = gde[tree1.niz[i]];
        tree2.niz[i] = gde[tree2.niz[i]];
    }
    for(int i=1; i<=n; i++){
        addbit(tree2.niz[i]);
        for(auto ind : queries[i]){
            int kf = 1;
            if(ind < 0){
                kf = -1;
                ind = -ind;
            }
            soln[ind-1] += kf*getbit(r1[ind-1]);
            soln[ind-1] -= kf*getbit(l1[ind-1] - 1);
        }
    }
    for(int i=0; i<qrs; i++) if(soln[i] > 0) soln[i] = 1;
    return soln;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...