bitset 优化最长公共子序列

#include <cstdio>
#include <cstring>
#include <algorithm>

const int MAXN = 5005, SIGMA = 26;

struct Bitset {
    static constexpr int W = 62;

    static constexpr size_t size = MAXN / W + !!(MAXN % W);
    unsigned long long u[size];

    Bitset &operator=(const Bitset &rhs) {
        std::copy(rhs.u, rhs.u + size, u);
        return *this;
    }

    void reset() {
        std::fill(u, u + size, 0);
    }
    void set(int x) {
        u[x / W] |= 1ull << (x % W);
    }
    bool get(int x) const {
        return u[x / W] & (1ull << (x % W));
    }

    Bitset operator|(const Bitset &rhs) const {
        Bitset res;
        for (int i = 0; i < size; i++) res.u[i] = u[i] | rhs.u[i];
        return res;
    }
    Bitset operator&(const Bitset &rhs) const {
        Bitset res;
        for (int i = 0; i < size; i++) res.u[i] = u[i] & rhs.u[i];
        return res;
    }
    Bitset operator^(const Bitset &rhs) const {
        Bitset res;
        for (int i = 0; i < size; i++) res.u[i] = u[i] ^ rhs.u[i];
        return res;
    }

    Bitset operator-(const Bitset &rhs) const {
        Bitset res;
        for (int i = 0; i < size; i++) res.u[i] = u[i] - rhs.u[i];
        for (int i = 0; i < size; ++ i) if (res.u[i] < 0) {
            res.u[i] += 1ll << W;
            --res.u[i + 1];
        }
        res.u[size] = 0;
        return res;
    }

    void shlOr1() {
        unsigned long long c = 1;
        for (int i = 0; i < size; ++ i) {
            u[i] <<= 1; u[i] |= c;
            c = u[i] >> W & 1;
            u[i] ^= c << W;
        }
    }

    size_t count() const {
        size_t res = 0;
        for (int i = 0; i < size; ++ i) res += __builtin_popcountll(u[i]);
        return res;
    }
};
Bitset row, as[SIGMA], x;

char s[MAXN], t[MAXN];

int main() {
    scanf("%s %s", s, t);
    int n = strlen(s), m = strlen(t);

    for (int i = 0; i < SIGMA; i++) as[i].reset();
    for (int i = 0; i < n; i++) as[s[i] - 'a'].set(i);

    row.reset();
    for (int i = 0; i < m; i++) {
        x = row | as[t[i] - 'a'];
        row.shlOr1();
        row = x - row;
        row = (row ^ x) & x;
        printf("%d\n", row.count());
    }
    return 0;
}

results matching ""

    No results matching ""