CF383E Vowels 子集DP 容斥

题意:

戳这里

分析:

首先很容易想到枚举元音字符集然后统计答案,至于统计答案可以采用容斥的方式得到,但是枚举元音字符集的子集复杂度是 (O(3^{24})) 的复杂度不对,我们发现这样枚举的情况下许多状态其实是无用的,压根不会出现的,所以我们考虑枚举每一个单词的子集来容斥,得到元音恰好为 (x) 的时候有多少个单词恰好包含这个字符集,最后再把每一个子集的答案加到子集身上,复杂度 (O(n*2^3+2^{24} imes 24))

代码:

#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
    const int maxn = (1<<24)+5;
    int n,ans;
    int f[maxn];
    char ch[5];

    void work()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch+1);
            int tmp=0;
            for(int i=1;i<=3;i++) tmp|=(1<<(ch[i]-'a'));
            for(int i=tmp;i;i=(i-1)&tmp)
            {
                if(__builtin_popcount(i)&1) f[i]++;
                else f[i]--;
            }
        }
        for(int i=0;i<24;i++)
        {
            for(int j=0;j<(1<<24);j++)
            {
                if(j&(1<<i)) f[j]+=f[(j^(1<<i))];
            }
        }
        for(int i=0;i<(1<<24);i++) ans^=(f[i]*f[i]);
        printf("%d
",ans);
    }

}

int main()
{
    zzc::work();
    return 0;
}

原文地址:https://www.cnblogs.com/youth518/p/14327603.html