답안 #866395

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
866395 2023-10-26T04:39:07 Z The_Samurai Alternating Current (BOI18_alternating) C++17
0 / 100
399 ms 1048576 KB
//#pragma GCC optimize("O3")
//#pragma GCC target("avx2")
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
const ll inf = 1e18;

const int M = 4100;
random_device rd;

struct bits{
    int n, k; // size and block_count
    unsigned long long *b;
    int cnt; // count of set bits

    inline void init(int _n){
        n = _n;
        k = (n + 63) / 64;
        cnt = 0;
        b = (unsigned long long *) calloc(k, sizeof(unsigned long long));
    }

    bits(){};

    bits(int _n){
        init(_n);
    }

    bits(const bits& from) : n(from.n), k(from.k), cnt(from.cnt){
        b = (unsigned long long *) calloc(k, sizeof(unsigned long long));
        memcpy(b, from.b, sizeof(b));
    };

    void set(int i){
        assert(0 <= i && i < n);
        if (!((b[i / 64] >> (i % 64)) & 1)){
            cnt++;
            b[i / 64] |= (1ull << (i % 64));
        }
    }

    void reset(int i){
        assert(0 <= i && i < n);
        if ((b[i / 64] >> (i % 64)) & 1){
            cnt--;
            b[i / 64] &= ULLONG_MAX ^ (1ull << (i % 64));
        }
    }

    void flip(int i){
        assert(0 <= i && i < n);
        if ((b[i / 64] >> (i % 64)) & 1){
            reset(i);
        } else {
            set(i);
        }
    }

    void set(){
        cnt = n;
        for (int i = 0; i + 1 < k; i++) b[i] = ULLONG_MAX;
        b[k - 1] = (1ull << (n % 64)) - 1;
    }

    void reset(){
        cnt = 0;
        for (int i = 0; i < k; i++) b[i] = 0;
    }

    void flip(){
        cnt = n - cnt;
        for (int i = 0; i + 1 < k; i++) b[i] ^= ULLONG_MAX;
        b[k - 1] ^= (1ull << (n % 64)) - 1;
    }

    bool test(int i) const{
        assert(0 <= i && i < n);
        return (b[i / 64] >> (i % 64)) & 1;
    }

    int count() const{
        return cnt;
    }

    bool any_of() const{
        return cnt > 0;
    }

    bool none_of() const{
        return cnt == 0;
    }

    bool all_of() const{
        return cnt == n;
    }

    int find_first(){
        if (cnt == 0) return n;
        int i = 0;
        while (i < k && b[i] == 0) i++;
        return i * 64 + __builtin_ctzll(b[i]);
    }

    int find_next(int i){ // first set bit >= i
        int j = i / 64;
        unsigned long long val = b[j];
        val &= ULLONG_MAX ^ ((1ull << (i % 64)) - 1);
        if (val != 0) return j * 64 + __builtin_ctzll(val);

        j++;
        while (j < k && b[j] == 0) j++;

        if (j == k) return n;
        return j * 64 + __builtin_ctzll(b[j]);
    }

    bits operator|= (const bits &other){
        assert(n == other.n);
        cnt = 0;
        for (int i = 0; i < k; i++){
            this->b[i] |= other.b[i];
            cnt += __builtin_popcountll(this->b[i]);
        }
        return *this;
    }

    bits operator| (const bits &other){
        bits res = *this;
        res |= other;
        return res;
    }

    bits operator&= (const bits &other){
        assert(n == other.n);
        cnt = 0;
        for (int i = 0; i < k; i++){
            this->b[i] &= other.b[i];
            cnt += __builtin_popcountll(this->b[i]);
        }
        return *this;
    }

    bits operator& (const bits &other){
        bits res = *this;
        res &= other;
        return res;
    }

    bits operator^= (const bits &other){
        assert(n == other.n);
        cnt = 0;
        for (int i = 0; i < k; i++){
            this->b[i] ^= other.b[i];
            cnt += __builtin_popcountll(this->b[i]);
        }
        return *this;
    }

    bits operator^ (const bits &other){
        bits res = *this;
        res ^= other;
        return res;
    }

    bits operator>>= (const int t){
        if (t >= n){
            reset();
        } else {
            for (int i = t; i < n; i++) {
                if (test(i)) {
                    set(i - t);
                } else {
                    reset(i - t);
                }
            }
            for (int i = n - t; i < n; i++) {
                reset(i);
            }
        }
        return *this;
    }

    bits operator>> (const int t){
        bits res = *this;
        res >>= t;
        return res;
    }

    bits operator<<= (const int t){
        if (t >= n){
            reset();
        } else {
            for (int i = n - t - 1; i >= 0; i--) {
                if (test(i)) {
                    set(i + t);
                } else {
                    reset(i + t);
                }
            }
            for (int i = 0; i < t; i++) {
                reset(i);
            }
        }
        return *this;
    }

    bits operator<< (const int t){
        bits res = *this;
        res <<= t;
        return res;
    }

};

int main() {
    srand(time(0));
    cin.tie(0)->sync_with_stdio(false);
#ifdef sunnatov
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int n, m, k;
    cin >> n >> m >> k;
    vector<string> a(n);
    for (string &s: a) cin >> s;
    vector<bits> bs(n);
    for (int i = 0; i < n; i++) bs[i].init(4 * m);
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) {
        if (a[i][j] == 'A') bs[i].set(4 * j);
        if (a[i][j] == 'C') bs[i].set(4 * j + 1);
        if (a[i][j] == 'G') bs[i].set(4 * j + 2);
        if (a[i][j] == 'T') bs[i].set(4 * j + 3);
    }
    vector ok(n, vector(n, -1));
    vector<int> pos(n);
    iota(pos.begin(), pos.end(), 0);
    shuffle(pos.begin(), pos.end(), rd);
    for (int i = 0; i < min(10, n); i++) {
        for (int j = 0; j < n; j++) {
            if (pos[i] == j) continue;
            if ((bs[pos[i]] ^ bs[j]).count() != 2 * k) {
                ok[pos[i]][j] = ok[j][pos[i]] = 0;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        if (count(ok[i].begin(), ok[i].end(), 0)) continue;
        for (int j = 0; j < n; j++) {
            if (i == j or ok[i][j] == 1) continue;
            if ((bs[i] ^ bs[j]).count() != 2 * k) {
                ok[i][j] = ok[j][i] = 0;
                break;
            } else {
                ok[i][j] = ok[j][i] = 1;
            }
        }
        if (!count(ok[i].begin(), ok[i].end(), 0)) {
            cout << i + 1;
            return 0;
        }
    }

}

Compilation message

alternating.cpp: In copy constructor 'bits::bits(const bits&)':
alternating.cpp:31:27: warning: argument to 'sizeof' in 'void* memcpy(void*, const void*, size_t)' call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess]
   31 |         memcpy(b, from.b, sizeof(b));
      |                           ^~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 348 KB Unexpected end of file - token expected
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 348 KB Unexpected end of file - token expected
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 348 KB Unexpected end of file - token expected
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 399 ms 1048576 KB Execution killed with signal 9
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 348 KB Unexpected end of file - token expected
2 Halted 0 ms 0 KB -