hdu6021[BestCoder #93] MG loves string
这场BC实在是有趣啊,T2是个没有什么算法但是细节坑的贪心+分类讨论乱搞,T3反而码起来很顺.
然后出现了T2过的人没有T3多的现象(T2:20人,T3:30人),而且T2的AC率是惨烈的不到3%
(我T2读入写挂,思路想挂,推倒重码一次,交了7次才过QAQ)
最后狂码T3赶在结束之前调出来过了,3题最后都没有被叉也没有fst,捡了个rk9,人品好啊.
题意
给出26个字母的一个排列,对一个字符串进行一次变换表示将某个字母变成排列中对应的字母.
例如zabcdefg....wxy,1表示经过一次变换之后,所有的'a'会变成'z','b'会变成'a','c'会变成'b'...
一个长度为N的随机串经过若干次变换之后必然得到本身.那么我们可以求出得到本身的最小变换次数.
长度为N的串有\(26^N\)个,求这些串的最小变换次数之和.\(N<=10^9\)
分析
给出的置换中,对于某一个字母,它至少变换多少次之后得到自身是已知的.对于某一个随机串,它变换到
自己的最小步数只和出现过的字母种类有关,对出现过的字母变换到自身的最小步数求lcm即可.那么我们
对出现过的字母种类进行状压,用\(f[i][S]\)表示前i个字母中出现的字母集合为S的方案数.那么\(f[i-1][]\)
到\(f[i][]\)的转移是可以看作矩阵乘法形式的,于是我们可以在\(2^{26}logN\)的时间内解决暴力.
仔细分析.如果某个字母变换到自己的最小次数是3,那么它位于一个长度为3的循环中,这3种字母变换到自己
的最小步数是相同的,因此可以在状态压缩的时候视为一种.如果两个字母处在不同的循环但是长度相同,例如
"badc....",'a,'b','c','d'的最小步数均为2,也可以视为一种.那么长度为26的串里最多出现6种不同的
循环长度,我们就可以在\(O(2^6logN)\)内解决.也可以dfs枚举出所有可行的lcm,数量不会比2^6多.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int mod=1000000007;
int sz;
struct matrix{
int a[130][130];
matrix(){
memset(a,0,sizeof(a));
}
matrix(int x){
memset(a,0,sizeof(a));
for(int i=0;i<130;++i){
a[i][i]=x;
}
}
matrix operator *(const matrix &B)const{
matrix C;
for(int i=1;i<=sz;++i){
for(int j=1;j<=sz;++j){
for(int k=1;k<=sz;++k){
C.a[i][k]=(C.a[i][k]+a[i][j]*1ll*B.a[j][k])%mod;
}
}
}
return C;
}
};
matrix qpow(matrix A,int x){
matrix ans(1);
for(;x;x>>=1,A=A*A){
if(x&1)ans=ans*A;
}
return ans;
}
char buf[30];
int a[30];
int vis[30],T;
int w[30];
int b[30];int tot=0;
int lcm[1024];int totlcm=0;
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int LCM(int a,int b){
return a/gcd(a,b)*b;
}
void dfs(int x,int tmp){
if(x==tot+1){
lcm[++totlcm]=tmp;
return;
}else{
dfs(x+1,tmp);
dfs(x+1,LCM(tmp,b[x]));
}
}
matrix A,ANS;
int main(){
int tests;scanf("%d",&tests);
while(tests--){
tot=0;
int n;scanf("%d",&n);
scanf("%s",buf+1);
for(int i=1;i<=26;++i){
a[i]=buf[i]-'a'+1;
}
++T;
for(int i=1;i<=26;++i){
if(vis[i]!=T){
int cnt=0;
for(int j=i;vis[j]!=T;j=a[j]){
cnt++;vis[j]=T;
}
b[++tot]=cnt;
w[i]=cnt;
for(int j=a[i];j!=i;j=a[j]){
w[j]=cnt;
}
}
}
sort(b+1,b+tot+1);
int sum=0;
for(int i=1;i<=tot;++i){
if(b[i]!=b[i-1]){
b[++sum]=b[i];
}
}
tot=sum;
totlcm=0;
dfs(1,1);
sort(lcm+1,lcm+totlcm+1);
sum=0;
for(int i=1;i<=totlcm;++i){
if(lcm[i]!=lcm[i-1])lcm[++sum]=lcm[i];
}
totlcm=sum;
A=matrix(0);
map<int,int> dict;
for(int i=1;i<=totlcm;++i)dict[lcm[i]]=i;
for(int i=1;i<=totlcm;++i){
for(int j=1;j<=26;++j){
A.a[i][dict[LCM(lcm[i],w[j])]]++;//printf("%d %d\n",i,dict[LCM(lcm[i],w[j])]);
}
}sz=totlcm;
ANS=qpow(A,n);
int ans=0;
for(int i=1;i<=totlcm;++i){
ans=(ans+lcm[i]*1ll*ANS.a[1][i])%mod;
}
printf("%d\n",ans);
// for(int i=1;i<=totlcm;++i)printf("%d ",lcm[i]);printf("\n");
// for(int i=1;i<=tot;++i)printf("%d ",b[i]);printf("\n");
}
return 0;
}
hdu6021[BestCoder #93] MG loves string的更多相关文章
- 【HDU 6021】 MG loves string (枚举+容斥原理)
MG loves string Accepts: 30 Submissions: 67 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- hdu 6021 MG loves string
MG loves string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others ...
- 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
题链: http://acm.hdu.edu.cn/showproblem.php?pid=6021 题解: 题意:对于一个长度为 N的由小写英文字母构成的随机字符串,当它进行一次变换,所有字符 i ...
- hdu 6020 MG loves apple 恶心模拟
题目链接:点击传送 MG loves apple Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Ja ...
- best corder MG loves gold
MG loves gold Accepts: 451 Submissions: 1382 Time Limit: 3000/1500 MS (Java/Others) Memory Limit ...
- (set)MG loves gold hdu6019
MG loves gold Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- 【HDU 6020】 MG loves apple (乱搞?)
MG loves apple Accepts: 20 Submissions: 693 Time Limit: 3000/1500 MS (Java/Others) Memory Limit: ...
随机推荐
- 20155319 实验二 Java面向对象程序设计
20155319 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 (一) ...
- Spring框架实例
一,介绍 Spring框架核心是Ioc控制反转,只要在容器中注册以后,依赖从容器中获取即可 简单的理解:需要一个值,在程序中定义一个变量,但是不赋值,只设置set方法,运行时,容器为该变量赋值 二,实 ...
- [BZOJ2961]共点圆-[凸包+cdq分治]
Description 传送门 Solution 考虑对于每一个点: 设圆的坐标为(x,y),点的坐标为(x0,y0).依题意得,当一个点在圆里,需要满足(x-x0)2+(y-y0)2<=x2+ ...
- 【转载】C/C++杂记:虚函数的实现的基本原理
原文:C/C++杂记:虚函数的实现的基本原理 1. 概述 简单地说,每一个含有虚函数(无论是其本身的,还是继承而来的)的类都至少有一个与之对应的虚函数表,其中存放着该类所有的虚函数对应的函数指针.例: ...
- pyhon3.0 day01 变量、输入、输出、循环
pyhon3.0 基础01 1 python解释器 Python的解释器很多,但使用最广泛的还是CPython.如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython, ...
- 在BAE上部署Pomelo
BAE升级到3.0后顿时感觉好用了很多,俨然云主机的感觉. 底下我将分享我在BAE上部署Pomelo的过程. 首先需要拥有一个BAE的执行单元.没有的可以自行百度并部署. 接着svn得出代码到本地.此 ...
- NO.02---聊聊Vue提升
如果本篇有看不明白的地方,请翻阅上一篇文章 上一篇我们讲了如何通过一些简单的动作来改变 store.js 中的数据对象,在实际工作中,这是完全无法满足工作需求的,所以这篇我们来说说如何做一些简单的流程 ...
- 2019CSUST集训队选拔赛题解(一)
来自ppq的毒瘤线段树 Sneakers Description 有一天喜欢买鞋的ppq和小伙伴来到了某一家球鞋店,球鞋店有n种球鞋,价格分别为ai,ppq在鞋店兜兜转转,发现鞋店老板会偶尔将某段 ...
- IT工具使用
linux 其他知识目录 常用快捷键总结 博客view code 删除,先删除,再清除格式
- win10 tomcat不能访问问题
问题描述:电脑是Win10系统的,安装了Tomcat后,本机通过80端口能顺利访问.但局域网内的其他机器却无法访问这台电脑的Tomcat服务. 故障分析: 将防火墙关闭后,可以访问,所以问题就出在防火 ...