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;
}