题链:

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的更多相关文章

  1. hdu 6021 MG loves string

    MG loves string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others ...

  2. hdu 6021 MG loves string (一道容斥原理神题)(转)

    MG loves string    Accepts: 30    Submissions: 67  Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  3. 【HDU 6021】 MG loves string (枚举+容斥原理)

    MG loves string  Accepts: 30  Submissions: 67  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: ...

  4. MG loves string

    MG loves string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others ...

  5. hdu 6020 MG loves apple 恶心模拟

    题目链接:点击传送 MG loves apple Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Ja ...

  6. hdu6021[BestCoder #93] MG loves string

    这场BC实在是有趣啊,T2是个没有什么算法但是细节坑的贪心+分类讨论乱搞,T3反而码起来很顺. 然后出现了T2过的人没有T3多的现象(T2:20人,T3:30人),而且T2的AC率是惨烈的不到3% ( ...

  7. 【HDU 6020】 MG loves apple (乱搞?)

    MG loves apple  Accepts: 20  Submissions: 693  Time Limit: 3000/1500 MS (Java/Others)  Memory Limit: ...

  8. best corder MG loves gold

    MG loves gold  Accepts: 451  Submissions: 1382  Time Limit: 3000/1500 MS (Java/Others)  Memory Limit ...

  9. Hdu 5806 NanoApe Loves Sequence Ⅱ(双指针) (C++,Java)

    Hdu 5806 NanoApe Loves Sequence Ⅱ(双指针) Hdu 5806 题意:给出一个数组,求区间第k大的数大于等于m的区间个数 #include<queue> # ...

随机推荐

  1. Hibernate之Hibernate的体系结构

    体系结构简图: 这是一张体系结构的简图,其中的hibernate.properties文件的作用相当于配置文件hibernate.cfg.xml XML Mapping对应的就是映射文件 XXXX.h ...

  2. Struts2之Struts2的下载与安装

    Struts2的下载 登陆struts的官网 下载Full Distribution这个选项的struts2的包. 这是Struts2的完整版,里面包括Struts2的实例应用,空实例应用,核心库,源 ...

  3. UTF-8 UTF-16 UTF-32 最根本的区别?

    昨天看书的时候突然发现UTF-16 我好像还没见过这个东西  也可能忘记了 反正现在对自己科普一下吧 最根本的区别 UTF-32 把所有的字符都用32bit -- 4个字节 来表示 UTF-16 和 ...

  4. java.lang.String 类源码解读

    String类定义实现了java.io.Serializable, Comparable<String>, CharSequence 三个接口:并且为final修饰. public fin ...

  5. 由路由器AP隔离引起的WEB服务不能访问的问题

    最近在自己的电脑上运行了一个Web服务,发现它只能被本机访问,无法在同一个局域网的其它设备访问. 于是在网上搜索了各种资料,通通都是在操作系统层面来分析解决问题的. 而我怎么尝试都不成功的情况下,差点 ...

  6. linux下git常用命令

    1 安装: sudo apt-get install git 2 创建一个版本库: 新建一个文件夹,进入这个目录之后 git init 3 创建一个版本: git add 文件名或目录 #表示将当前文 ...

  7. SpringBoot框架中JPA使用的一些问题

    主要是自己在使用JPA框架时遇到的一个坑,拿出来分享一下 首先上一个简单JPA框架实体 public interface EnterpriseInfoDao extends JpaSpecificat ...

  8. tornado框架源码分析---Application类之debug参数

    先贴上Application这个类的源码. class Application(httputil.HTTPServerConnectionDelegate): """A ...

  9. Android:触屏事件

    Android触屏事件包含两种: 1)屏幕触屏事件:重写onTouchEvent(MotionEvent event): 2)控件触屏事件:给控件注册触屏事件,setOnTouchEventListe ...

  10. Java:Linux上java -jar xxx.jar命令执行jar包时出现Error: Invalid or corrupt jarfile xxx.jar解决方案

    背景: 从ftp上上传jar包到linux上,之后在linux上通过ftp命令下载jar包文件,开始执行Java-jar,一直提示错误:Error: Invalid or corrupt jarfil ...