답안 #963923

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
963923 2024-04-16T03:35:10 Z steveonalex CEOI16_icc (CEOI16_icc) C++17
100 / 100
105 ms 872 KB
#include <bits/stdc++.h>
#include "icc.h"
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
#define ALL(v) (v).begin(), (v).end()
#define MASK(i) (1LL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
 
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rng(1);
ll rngesus(ll l, ll r){return ((ull) rng()) % (r - l + 1) + l;}
 
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);}
ll pop_cnt(ll mask){return __builtin_popcountll(mask);}
ll ctz(ll mask){return __builtin_ctzll(mask);}
ll clz(ll mask){return __builtin_clzll(mask);}
ll logOf(ll mask){return 63 - clz(mask);}
 
template <class T1, class T2>
    bool minimize(T1 &a, T2 b){
        if (a > b){a = b; return true;}
        return false;
    }
template <class T1, class T2>
    bool maximize(T1 &a, T2 b){
        if (a < b){a = b; return true;}
        return false;
    }
template <class T>
    void printArr(T& a, string separator = " ", string finish = "\n", ostream& out = cout){
        for(auto i: a) out << i << 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;

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

    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){
        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];
            return true;
        }
        return false;
    }
};

// const int N = 101;

// namespace Grader{
//     vector<pair<int, int>> edge;
//     bool graph[N][N];
//     bool ans;
//     int o_cnt;

//     void setRoad(int u, int v){
//         if (u > v) swap(u, v);
//         if (make_pair(u, v) != edge.back()) ans = false;
//         edge.pop_back();
//         if (edge.empty()) return;
//         graph[edge.back().first][edge.back().second] = true;
//         graph[edge.back().second][edge.back().first] = true;
//     }

//     int query(int sz1, int sz2, int* a, int* b){
//         o_cnt++;
//         for(int i = 0; i<sz1; ++i) for(int j = 0; j<sz2; ++j)
//             if (graph[a[i]][b[j]]) return 1;
//         return 0;
//     }

void run(int n){
    DSU mst(n);
    for(int i = 1; i<n; ++i){
        vector<int> cur;
        for(int j = 1; j<=n; ++j) if (mst.find_set(j) == j) cur.push_back(j);
        vector<vector<int>> cc(cur.size());
        for(int j = 1; j<=n; ++j) {
            int x = mst.find_set(j);
            x = lower_bound(ALL(cur), x) - cur.begin();
            cc[x].push_back(j);
        }

        int diff = 0;
        for(int j = 0; MASK(j) < cur.size(); ++j){
            vector<int> left, right;
            for(int k = 0; k < cur.size(); ++k) if (GETBIT(k, j)) {
                for(int t: cc[k]) right.push_back(t);
            }
            else{
                for(int t: cc[k]) left.push_back(t);
            }

            int sz1 = left.size(), sz2 = right.size();
            int a[sz1], b[sz2];
            for(int i = 0; i<sz1; ++i) a[i] = left[i];
            for(int i = 0; i<sz2; ++i) b[i] = right[i];
            if (query(sz1, sz2, a, b)) diff += MASK(j);
        }

        vector<int> S1, S2;
        for(int j = 0; j < cur.size(); ++j) {
            int k = (j ^ diff);
            if (k < cur.size() && j < k){
                for(int t: cc[j]) S1.push_back(t);
                for(int t: cc[j ^ diff]) S2.push_back(t);
            }
        }

        int l = 0, r = S1.size();
        while(l < r){
            int mid = (l + r) >> 1;
            int sz1 = mid + 1, sz2 = S2.size();
            int a[sz1], b[sz2];
            for(int i = 0; i<sz1; ++i) a[i] = S1[i];
            for(int i = 0; i<sz2; ++i) b[i] = S2[i];
            if (query(sz1, sz2, a, b)) r = mid;
            else l = mid + 1;
        }

        int u = S1[l];

        int y = (lower_bound(ALL(cur), mst.find_set(u)) - cur.begin()) ^ diff;
        l = 0, r = cc[y].size();

        while(l < r){
            int mid = (l + r) >> 1;
            int sz1 = S1.size(), sz2 = mid + 1;
            int a[sz1], b[sz2];
            for(int i = 0; i<sz1; ++i) a[i] = S1[i];
            for(int i = 0; i<sz2; ++i) b[i] = cc[y][i];
            if (query(sz1, sz2, a, b)) r = mid;
            else l = mid + 1;
        }

        int v = cc[y][l];

        setRoad(u, v);
        mst.join_set(u, v);
    }
}

//     bool solve(int n){
//         edge.clear(); memset(graph, 0, sizeof graph);
//         for(int i = 2; i<=n; ++i) edge.push_back({rngesus(1, i-1), i});
//         // reverse(ALL(edge));
//         // shuffle(ALL(edge), rng);
//         ans = 1;
//         o_cnt = 0;

//         graph[edge.back().first][edge.back().second] = true;
//         graph[edge.back().second][edge.back().first] = true;

//         run(n);

//         return ans && edge.size() == 0;
//     }

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

//     // int n; cin >> n;
//     int n = 100;
//     cout << Grader::solve(n) << "\n";

//     cout << Grader::o_cnt << "\n";
 
//     return 0;
// }

Compilation message

icc.cpp: In function 'void run(int)':
icc.cpp:109:32: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  109 |         for(int j = 0; MASK(j) < cur.size(); ++j){
      |                                ^
icc.cpp:111:30: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  111 |             for(int k = 0; k < cur.size(); ++k) if (GETBIT(k, j)) {
      |                            ~~^~~~~~~~~~~~
icc.cpp:126:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  126 |         for(int j = 0; j < cur.size(); ++j) {
      |                        ~~^~~~~~~~~~~~
icc.cpp:128:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  128 |             if (k < cur.size() && j < k){
      |                 ~~^~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 600 KB Ok! 116 queries used.
2 Correct 5 ms 600 KB Ok! 115 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 600 KB Ok! 580 queries used.
2 Correct 34 ms 664 KB Ok! 512 queries used.
3 Correct 27 ms 604 KB Ok! 553 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 105 ms 620 KB Ok! 1478 queries used.
2 Correct 83 ms 600 KB Ok! 1259 queries used.
3 Correct 80 ms 620 KB Ok! 1371 queries used.
4 Correct 99 ms 624 KB Ok! 1445 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 83 ms 640 KB Ok! 1390 queries used.
2 Correct 95 ms 620 KB Ok! 1381 queries used.
3 Correct 79 ms 856 KB Ok! 1320 queries used.
4 Correct 88 ms 872 KB Ok! 1481 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 87 ms 628 KB Ok! 1362 queries used.
2 Correct 82 ms 624 KB Ok! 1343 queries used.
3 Correct 90 ms 612 KB Ok! 1336 queries used.
4 Correct 81 ms 600 KB Ok! 1392 queries used.
5 Correct 91 ms 636 KB Ok! 1496 queries used.
6 Correct 92 ms 604 KB Ok! 1386 queries used.
# 결과 실행 시간 메모리 Grader output
1 Correct 83 ms 624 KB Ok! 1385 queries used.
2 Correct 79 ms 640 KB Ok! 1255 queries used.