F
题意:
就是给你n个键盘,每个键盘可以打一些字母,然后让你用键盘打出长度为m的字母的方案数有多少种。
思考:
刚开始我以为是每次只能用一个键盘,实际上可以随便用。但是很明显有k个字母的方案数就是k的m次方,但是怎么去重呢。其实根据去重原理,最简单的是3个键盘,1+2+3-12-13-23+123。然后递推一下就是对于一个多重集合去重的就是二进制枚举用了几个键盘,然后如果是奇数个就加上方案数,如果是偶数个就减去方案数。对了对于求方案的时候,是这些键盘共有的字母的方案数。
代码:
int T,n,m,k;
int va[N];
int ksm(int a,int b)
{
int sum = 1;
while(b)
{
if(b&1) sum = sum*a%mod;
a = a*a%mod;
b >>= 1;
}
return sum;
}
signed main()
{
IOS;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
string s;
cin>>s;
for(auto t:s) va[i] |= 1ll<<(t-'a');
}
int ans = 0;
for(int i=1;i<(1ll<<n);i++)
{
int now = (1ll<<26)-1,cnt = 0,res = 0;
for(int j=0;j<n;j++)
{
if(i>>j&1)
{
cnt++;
now &= va[j+1];
}
}
for(int j=0;j<26;j++) if(now>>j&1) res++;
if(cnt%2) ans = (ans+ksm(res,m))%mod;
else ans = (ans-ksm(res,m))%mod;
}
ans = (ans%mod+mod)%mod;
cout<<ans;
return 0;
}
总结:
多多思考积累经验。