CF1234F Yet Another Substring Reverse
你看字符集大小,显然状压,用1代表这个连续不同字符段(也就是题里定义的字符串)里面有这个字符。那么我们直接随便压一压,然后dp。
我们可以先处理出来 \(f_{i}\) 然后可以枚举它的补集,让这两个字符串拼接起来,答案就是 \(\max{f_{i}+f_{i \bigoplus ((1 <<20)-1)}}\)
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6+10, MAXM = 20;
ll N, M, f[1LL << (MAXM + 1)], ans;
char ss[MAXN];
int main() {
scanf("%s", ss+1);
N = strlen(ss+1);
for (ll i = 1; i <= N; i++) {
ll mk = 0;
for (ll j = 0; j < MAXM && i + j <= N; j++) {
ll now = ss[i + j] - 'a';
if (mk & (1LL << now)) break;
mk |= (1LL << now);
f[mk] = j + 1;
}
}
for (ll i = 0; i < (1LL << MAXM); i++)
for (ll j = 0; j < MAXM; j++)
if (i & (1LL << j))
f[i] = max(f[i], f[i ^ (1LL << j)]);
for (ll i = 0; i < (1LL << MAXM); i++)
ans = max(f[i] + f[i ^ ((1LL << MAXM)-1)], ans);
printf("%lld\n", ans);
return 0;
}
希望我们都有一个光明的未来