●HDU 6021 MG loves string
题链:
http://acm.hdu.edu.cn/showproblem.php?pid=6021
题解:
题意:
对于一个长度为 N的由小写英文字母构成的随机字符串,
当它进行一次变换,所有字符 i 都会变成a[i]。
同时变换数组:a[i]是26个字母组成的排列。
现在需要知道这个随机串变换到自身的期望变换次数。
请你输出期望答案乘上26^N以后模 1000000007的结果。
容斥,LCM
其实题目要求的就是每种串(共有 26^N种串)回到自身的变化次数之和。
暴力求法就是:
看每种串的每个字符在循环长度为多少的循环里(设第i个位置的字符的循环长度为 Di),
则该串的变化次数为 LCM(D1,D2,D3...,DN)(最小公倍数)
不难发现,对于给定的变化数组 a[ ],循环长度不同的循环节的种类个数不超过 6 个(1+2+3+4+5+6+7>26)
6很小,所以就可以在这个 "6" 上面搞事情。
枚举循环节的集合 S,表示串里的字符只能是这些循环节的字母集合里的字母。
就是把 N 个字符放到那些循环节的字母集合中去。
(假设这个集合的循环节只包含了 W 个字母)
但是我们要使得串的变化次数为 LCM(Di, ${i}\epsilon{S}$ ),(即答案为这些循环节长度的 LCM)
那么每个循环节里面都至少要有一个字符被在里面。
所以问题转化为:N个东西分到 M 个盒子,每个盒子都至少有一个东西。
求法如下:
设 f[S] 表示在 S集合的循环节里随便放的方案数,即每个字符可以随便选择 W 个字母里面的任意一个。
显然 f[S] = $W^N$。但是这个 f[S] 有非法方案,即存在某些循环节里没有放字符。
所以容斥如下:
ANS = 没有涵盖至少 0个循环节的方案数(即f[S])
-没有涵盖至少 1个循环节的方案数
+没有涵盖至少 2个循环节的方案数
-...+...
用于容斥的方案数就直接枚举 S 的子集 _S,(方案数即为 f[_S])。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define _ % mod
#define filein(x) freopen(#x".in","r",stdin);
#define fileout(x) freopen(#x".out","w",stdout);
using namespace std;
const int mod=1000000007;
int f[100],vis[100],d[100],g[100],h[100],tot;;
char S[100];
int T,N,ANS;
int gcd(int a,int b){
while(b^=a^=b^=a%=b);
return a;
}
int pow(int a,int b){
int now=1;
while(b){
if(b&1) now=(1ll*now*a)_;
a=(1ll*a*a)_; b>>=1;
}
return now;
}
void precircle(){
tot=0;
scanf("%d",&N);
scanf("%s",S+1);
memset(d,0,sizeof(d));
memset(h,0,sizeof(h));
memset(vis,0,sizeof(vis));
for(int i=1;i<=26;i++)
if(!vis[S[i]-'a'+1]){
int tmp=0,p=S[i]-'a'+1;
while(!vis[p]) tmp++,vis[p]=1,p=S[p]-'a'+1;
d[tmp]++;
}
for(int i=1;i<=26;i++)
if(d[i]) tot++,g[tot]=d[i],d[tot]=i;
for(int s=1,cnt;cnt=0,s<(1<<tot);s++){
for(int i=1;i<=tot;i++)
if(s&(1<<(i-1)))
cnt+=g[i]*d[i],h[s]++;
f[s]=pow(cnt,N);
}
/*for(int s=1,tmp;s<(1<<tot);s++){
for(int _s=s;_s;_s=(_s-1)&s){
if(s==_s) continue;
tmp=-f[_s];
tmp=(1ll*tmp+mod)_;
f[s]=(1ll*f[s]+tmp+mod)_;
}
}正推就不用容斥了*/
for(int s=1,tmp;s<(1<<tot);s++){
for(int _s=s;_s;_s=(_s-1)&s){
if(s==_s) continue;
tmp=-f[_s];
tmp=(1ll*tmp+mod)_;
f[s]=(1ll*f[s]+tmp+mod)_;
}
}//逆推需要容斥
}
void dfs(int p,int s,int lcm){
if(p==tot+1){
ANS=(1ll*ANS+(1ll*f[s]*lcm)_)_;
return;
}
dfs(p+1,s,lcm);
dfs(p+1,s|(1<<(p-1)),1ll*lcm/gcd(lcm,d[p])*d[p]);
}
int main()
{
scanf("%d",&T);
while(T--){
ANS=0;
precircle();
dfs(1,0,1);
printf("%d\n",ANS);
}
return 0;
}
●HDU 6021 MG loves string的更多相关文章
- hdu 6021 MG loves string
MG loves string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others ...
- hdu 6021 MG loves string (一道容斥原理神题)(转)
MG loves string Accepts: 30 Submissions: 67 Time Limit: 2000/1000 MS (Java/Others) Memory ...
- 【HDU 6021】 MG loves string (枚举+容斥原理)
MG loves string Accepts: 30 Submissions: 67 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- MG loves string
MG loves string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others ...
- hdu 6020 MG loves apple 恶心模拟
题目链接:点击传送 MG loves apple Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Ja ...
- hdu6021[BestCoder #93] MG loves string
这场BC实在是有趣啊,T2是个没有什么算法但是细节坑的贪心+分类讨论乱搞,T3反而码起来很顺. 然后出现了T2过的人没有T3多的现象(T2:20人,T3:30人),而且T2的AC率是惨烈的不到3% ( ...
- 【HDU 6020】 MG loves apple (乱搞?)
MG loves apple Accepts: 20 Submissions: 693 Time Limit: 3000/1500 MS (Java/Others) Memory Limit: ...
- best corder MG loves gold
MG loves gold Accepts: 451 Submissions: 1382 Time Limit: 3000/1500 MS (Java/Others) Memory Limit ...
- Hdu 5806 NanoApe Loves Sequence Ⅱ(双指针) (C++,Java)
Hdu 5806 NanoApe Loves Sequence Ⅱ(双指针) Hdu 5806 题意:给出一个数组,求区间第k大的数大于等于m的区间个数 #include<queue> # ...
随机推荐
- TCP和UDP的最完整的区别
TCP UDP TCP与UDP基本区别 1.基于连接与无连接 2.TCP要求系统资源较多,UDP较少: 3.UDP程序结构较简单 4.流模式(TCP)与数据报模式(UDP); ...
- java中<> 的用法
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引 ...
- 【iOS】Swift GCD-下
欢迎来到本GCD教程的第二同时也是最终部分! 在第一部分中,你学到了并发,线程以及GCD的工作原理.通过使用dispatch_barrrier和dispatch_sync,你做到了让PhotoMana ...
- vue内置指令详解——小白速会
指令 (Directives) 是带有 v- 前缀的特殊属性,职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM. 内置指令 1.v-bind:响应并更新DOM特性:例如:v-bi ...
- SUN平台服务器光纤共享存储互斥失败如何恢复数据?
服务器数据恢复故障描述: 服务器最初的设计思路为将两台SPARC SOLARIS系统通过光纤交换机共享同一存储作为CLUSTER使用,正常情况下A服务器工作,当A服务器发生故障宕机后即可将其关机然后开 ...
- slf4j 与 log4j2 基本用法
简单的说 log4j2 是log4j2的升级版,解决了部分性能问题和部分死锁问题,其使用方式与使用配置与log4j相同. 建议使用maven依赖直接使用log4j2 <dependency> ...
- 01-JavaScript之变量
这个系列的文章主要讲解JavaScript的常见用法,适合于初中级的前端开发人员,也可以对比TypeScript的系列文章来看. 先介绍JavaScript的变量与常见变量的函数,代码如下: //变量 ...
- cocos2d 判断旋转矩形是否包含某个点
本来想画个图演示一下,但是折腾了一会发现画不好,我的win10系统没有安装office,以后再看的话再补上吧.不废话了. 如图所以,如果判断点P是否被矩形A所包含,非常容易.那么如果矩形A以中心点逆时 ...
- JAVA_SE基础——42.final修饰符
高手勿喷~ final关键字可用于修饰类.变量和方法,它有"这是无法改变的"或者"最终"的含义,因此被final修饰的类.变量和方法将具有以下特征: 1.fin ...
- linux下面根据不同的日期创建不同文件,一般用户数据库的备份的shell编程
[root@www scripts]# vi sh03.sh #!/bin/bash # Program: # Program creates three files, which named by ...