답안 #987788

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
987788 2024-05-23T15:25:01 Z steveonalex 늑대인간 (IOI18_werewolf) C++17
0 / 100
1066 ms 124616 KB
#include <bits/stdc++.h>
#include "werewolf.h"
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
#define MASK(i) (1ULL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
#define ALL(v) (v).begin(), (v).end()
 
ll max(ll a, ll b){return (a > b) ? a : b;}
ll min(ll a, ll b){return (a < b) ? a : b;}
 
ll LASTBIT(ll mask){return (mask) & (-mask);}
int pop_cnt(ll mask){return __builtin_popcountll(mask);}
int ctz(ull mask){return __builtin_ctzll(mask);}
int logOf(ull mask){return 63 - __builtin_clzll(mask);}
 
mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);}
 
template <class T1, class T2>
    bool maximize(T1 &a, T2 b){
        if (a < b) {a = b; return true;}
        return false;
    }
 
template <class T1, class T2>
    bool minimize(T1 &a, T2 b){
        if (a > b) {a = b; return true;}
        return false;
    }
 
template <class T>
    void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){
        for(auto item: container) out << item << separator;
        out << finish;
    }
 
template <class T>
    void remove_dup(vector<T> &a){
        sort(ALL(a));
        a.resize(unique(ALL(a)) - a.begin());
    }

struct DSU{
    int n;
    vector<int> parent, sz;
    vector<vector<pair<int, int>>> chain;

    DSU(int _n){
        n = _n;
        parent.resize(n); sz.resize(n, 1);
        chain.resize(n);
        for(int i = 0; i<n; ++i){
            parent[i] = i;
            chain[i].push_back({i, -1});
        }
    }

    int find_set(int u){return (u == parent[u]) ? u : (parent[u] = find_set(parent[u]));}
    bool same_set(int u, int v){return find_set(u) != find_set(v);}

    bool join_set(int u, int v, int w = -1){
        u = find_set(u), v = find_set(v);
        if (u != v){
            if (sz[u] < sz[v]) swap(u, v);
            parent[v] = u;
            sz[u] += sz[v];
            chain[u].back().second = w;
            for(pair<int, int> i: chain[v]){
                chain[u].push_back(i);
            }
            chain[v].clear();
            return true;
        }
        return false;
    }

    vector<pair<int, int>> get_chain(){
        return chain[find_set(0)];
    }
};

struct FenwickTree{
    int n;
    vector<int> a;

    FenwickTree(int _n){
        n = _n;
        a.resize(n+1);
    }

    void update(int i, int w){
        while(i <= n){
            a[i] += w;
            i += LASTBIT(i);
        }
    }

    int get(int i){
        int ans = 0;
        while(i > 0){
            ans += a[i];
            i -= LASTBIT(i);
        }
        return ans;
    }

    int get(int l, int r){return get(r) - get(l-1);}
};

const int N = 2e5 + 69, LOG_N = 18, INF = 1e9 + 69;

int n, m, q;
int chain1[N], chain2[N];
int pos1[N], pos2[N];
int w1[LOG_N][N], w2[LOG_N][N];

int min_w(int l, int r){
    r--;
    if (l > r) return INF;
    int j = logOf(r - l + 1);
    return min(w1[j][l], w1[j][r - MASK(j) + 1]);
}

int max_w(int l, int r){
    r--;
    if (l > r) return INF;
    int j = logOf(r - l + 1);
    return max(w2[j][l], w2[j][r - MASK(j) + 1]);
}

pair<int, int> spread_min(int p, int cap){
    pair<int, int> ans = {p, p};
    int l = 0, r = p;
    while(l < r){
        int mid = (l + r) >> 1;
        if (min_w(mid, p) >= cap) r = mid;
        else l = mid + 1;
    }
    ans.first = l;
    l = p, r = n-1;
    while(l < r){
        int mid = (l + r + 1) >> 1;
        if (min_w(p, mid) >= cap) l = mid;
        else r = mid - 1;
    }
    ans.second = l;
    return ans;
}

pair<int, int> spread_max(int p, int cap){
    pair<int, int> ans = {p, p};
    int l = 0, r = p;
    while(l < r){
        int mid = (l + r) >> 1;
        if (max_w(mid, p) <= cap) r = mid;
        else l = mid + 1;
    }
    ans.first = l;
    l = p, r = n-1;
    while(l < r){
        int mid = (l + r + 1) >> 1;
        if (max_w(mid, p) <= cap) l = mid;
        else r = mid - 1;
    }
    ans.second = l;
    return ans;
}

int query[N];
vector<array<int, 3>> createQuery[N], destroyQuery[N];

vector<int> check_validity(int _n, vector<int> X, vector<int> Y,
                                vector<int> S, vector<int> E,
                                vector<int> L, vector<int> R) {
    n = _n, m = X.size();
    q = S.size();

    vector<int> ans(q);

    // build tree line for minimum node
    vector<array<int, 3>> min_edge(m);
    for(int i = 0; i<m; ++i)
        min_edge[i] = {{X[i], Y[i], min(X[i], Y[i])}};

    sort(ALL(min_edge), [](array<int, 3> x, array<int, 3> y){return x[2] > y[2];});

    DSU mst_min(n);
    for(auto i: min_edge)
        mst_min.join_set(i[0], i[1], i[2]);
    vector<pair<int,int>> min_chain = mst_min.get_chain();

    // build tree line for maximum node
    vector<array<int, 3>> max_edge(m);
    for(int i = 0; i<m; ++i)
        max_edge[i] = {{X[i], Y[i], max(X[i], Y[i])}};
    sort(ALL(max_edge), [](array<int, 3> x, array<int, 3> y){return x[2] < y[2];});

    DSU mst_max(n);
    for(auto i: max_edge)
        mst_max.join_set(i[0], i[1], i[2]);
    vector<pair<int,int>> max_chain = mst_max.get_chain();

    for(int i = 0; i<n; ++i) {
        chain1[i] = min_chain[i].first;
        pos1[chain1[i]] = i;

        chain2[i] = max_chain[i].first;
        pos2[chain2[i]] = i;

        w1[0][i] = min_chain[i].second;
        w2[0][i] = max_chain[i].second;
    }

    for(int j = 1; MASK(j) <= n; ++j)
    for(int i = 0; i + MASK(j) <= n; ++i){
        w1[j][i] = min(w1[j-1][i], w1[j-1][i + MASK(j-1)]);
        w2[j][i] = max(w2[j-1][i], w2[j-1][i + MASK(j-1)]);
    }

    for(int i = 0; i<n; ++i) query[pos1[i] + 1] = pos2[i] + 1;

    for(int i = 0; i < q; ++i){
        pair<int, int> spread1 = spread_min(pos1[S[i]], L[i]);
        pair<int, int> spread2 = spread_max(pos2[E[i]], R[i]);
        spread1.first++; spread1.second++; spread2.first++; spread2.second++;
        destroyQuery[spread1.first-1].push_back({{spread2.first, spread2.second, i}});
        createQuery[spread1.second].push_back({{spread2.first, spread2.second, i}});
    }

    FenwickTree bit(n);
    for(int i = 1; i<=n; ++i){
        bit.update(query[i], 1);
        for(array<int, 3> j: destroyQuery[i]){
            ans[j[2]] -= bit.get(j[0], j[1]);
        }
        for(array<int, 3> j: createQuery[i]){
            ans[j[2]] += bit.get(j[0], j[1]);
        }
    }

    for(int i = 0; i<q; ++i) ans[i] = (ans[i] > 0);

    return ans;
}



// int main(void){
//     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

//     int n, m, q; cin >> n >> m >> q;
//     vector<int> X, Y;
//     for(int i = 0; i<m; ++i){
//         int u, v; cin >> u >> v;
//         X.push_back(u); Y.push_back(v);
//     }

//     vector<int> S(q), E(q), L(q), R(q);
//     for(int i = 0; i<q; ++i){
//         cin >> S[i] >> E[i] >> L[i] >> R[i];
//     }

//     printArr(check_validity(n, X, Y, S, E, L, R));

//     return 0;
// }

Compilation message

werewolf.cpp: In function 'std::vector<int> check_validity(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:219:28: warning: comparison of integer expressions of different signedness: 'long long unsigned int' and 'int' [-Wsign-compare]
  219 |     for(int j = 1; MASK(j) <= n; ++j)
      |                            ^
werewolf.cpp:220:32: warning: comparison of integer expressions of different signedness: 'long long unsigned int' and 'int' [-Wsign-compare]
  220 |     for(int i = 0; i + MASK(j) <= n; ++i){
      |                    ~~~~~~~~~~~~^~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 8 ms 29276 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 8 ms 29276 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1066 ms 124616 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 8 ms 29276 KB Output isn't correct
2 Halted 0 ms 0 KB -