Codeforces Round #533 (Div. 2) E

E - Helping Hiasat

裸的最大团,写了一种 2 ^ (m / 2)  * (m / 2)的复杂度的壮压, 应该还有更好的方法。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long
using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;

int n, m, op;
LL e[40];
int a[1<<20], b[1<<20];
string name;
set<int> Set;
map<string, int> Map;

int main() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        cin >> op;
        if(op == 1) {
            Set.clear();
        } else {
            cin >> name;
            if(Map.find(name) == Map.end())
                Map[name] = SZ(Map);
            int x = Map[name];
            for(auto& y : Set) {
                e[x - 1] |= 1ll << (y - 1);
                e[y - 1] |= 1ll << (x - 1);
            }
            Set.insert(x);
        }
    }
    int c1 = m / 2, c2 = m - c1;
    for(int S = 1; S < (1 << c1); S++) {
        int p = __builtin_ctz(S), tmp = 0;
        a[S] = max(a[S], a[S ^ (1 << p)]);
        for(int i = 0; i < c1; i++)
            if(!(e[p]>>i&1)) tmp |= 1 << i;
        a[S] = max(a[S], a[tmp & (S ^ (1 << p))] + 1);
    }
    for(int S = 1; S < (1 << c2); S++) {
        int p = __builtin_ctz(S), tmp = 0;
        b[S] = max(b[S], b[S ^ (1 << p)]);
        for(int i = 0; i < c2; i++)
            if(!(e[p + c1]>>(i+c1)&1)) tmp |= 1 << i;
        b[S] = max(b[S], b[tmp & (S ^ (1 << p))] + 1);
    }
    int ans = 0;
    for(int S = 1; S < (1 << c2); S++) {
        LL tmp = 0;
        for(int i = 0; i < c2; i++)
            if(S >> i & 1) tmp |= e[i + c1];
        for(int i = 0; i < c1; i++) tmp ^= 1 << i;
        tmp &= (1 << c1) - 1;
        ans = max(ans, b[S] + a[tmp]);
    }
    printf("%d
", ans);
    return 0;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10333070.html