CF1234F Yet Another Substring Reverse

CF1234F

你看字符集大小,显然状压,用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;
}
posted @ 2020-10-16 09:16  Gensokyo_Alice  阅读(82)  评论(0编辑  收藏  举报