• [BZOJ2553][BeiJing2011]禁忌 dp+AC自动机+矩阵快速幂


    2553: [BeiJing2011]禁忌

    Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special Judge
    Submit: 1206  Solved: 607
    [Submit][Status][Discuss]

    Description

           Magic Land上的人们总是提起那个传说:他们的祖先John在那个东方岛屿帮助Koishi与其姐姐Satori最终战平。而后,Koishi恢复了读心的能力……

          

    如今,在John已经成为传说的时代,再次造访那座岛屿的人们却发现Koishi遇到了新麻烦。

           这次她遇到了Flandre Scarlet——她拥有可以使用禁忌魔法而不会受到伤害的能力。

           为了说明什么是禁忌魔法及其伤害,引入以下概念:

    1.字母集A上的每个非空字符串对应了一个魔法。

    其中A是包含了前alphabet个小写字母的集合。

    2.有一个集合T,包含了N个字母集A上的字符串

    T中的每一串称为一个禁忌串(Taboo string

    3.一个魔法,或等价地,其对应的串s因为包含禁忌而对使用者造成的伤害按以下方式确定:

               把s分割成若干段,考虑其中是禁忌串的段的数目,不同的分割可能会有不同的数目,其最大值就是这个伤害。

          

    由于拥有了读心的能力,Koishi总是随机地使用Flandre Scarlet的魔法,可以确定的是,她的魔法正好对应字母集A上所有长度为len的串

    但是,Flandre Scarlet所使用的一些魔法是带有禁忌的,由于其自身特性,她可以使用禁忌魔法而不受到伤害,而Koishi就不同了。可怜的Koishi每一次使用对方的魔法都面临着受到禁忌伤害的威胁。

     

           你现在需要计算的是如果Koishi使用对方的每一个魔法的概率是均等的,那么每一次随机使用魔法所受到的禁忌伤害的期望值是多少。

     

    Input

    第一行包含三个正整数Nlenalphabet

    接下来N行,每行包含一个串Ti,表示禁忌串。

     

    Output

    一个非负实数,表示所受到禁忌伤害的期望值。

    Sample Input

    2 4 2

    aa

    abb

    Sample Output

    0.75

    【样例1解释】
    一共有2^4 = 16种不同的魔法。

    需要注意的是“aabb”的禁忌伤害是1而不是2。

    HINT

    100%的数据中N ≤ 5len ≤1091 ≤ alphabet ≤ 26


    在所有数据中,有不少于40%的数据中:N = 1


    数据保证每个串Ti的长度不超过15,并且不是空串。


    数据保证每个Ti均仅含有前alphabet个小写字母。


    数据保证集合T中没有相同的元素,即对任意不同的ij,有TiTj


    【评分方法】


    对于每一组数据,如果没有得到正确的输出(TLE、MLE、RTE、输出格式错误等)得0分。


    否则:设你的输出是YourAns,标准输出是StdAns


    MaxEPS = max(1.0 , StdAns)×10-6


    如果|YourAns – StdAns| ≤ MaxEPS则得10分,否则得0分。


    即:你的答案需要保证相对误差或绝对误差不超过10-6

    Source

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define maxn 200
     8 using namespace std;
     9 int q[maxn],al,n,m;
    10 struct mat {
    11     long double f[maxn][maxn];
    12     mat() {for(int i=0;i<maxn;i++) for(int j=0;j<maxn;j++) f[i][j]=0;}
    13 }Ans;
    14 struct AC {
    15     int ch[maxn][26],fail[maxn],cnt,val[maxn];
    16     void build(char *s) {
    17         int now=0,len=strlen(s+1);
    18         for(int i=1;i<=len;i++) {
    19             int to=s[i]-'a';
    20             if(!ch[now][to]) ch[now][to]=++cnt;
    21             now=ch[now][to];
    22         }
    23         val[now]=1;
    24     }
    25     void getfail() {
    26         int h=0,t=0;
    27         for(int i=0;i<al;i++) if(ch[0][i]) q[t++]=ch[0][i];
    28         while(h!=t) {
    29             int now=q[h++];if(h==200) h=0;
    30             for(int i=0;i<al;i++) {
    31                 int to=ch[now][i];
    32                 if(!to) {ch[now][i]=ch[fail[now]][i];continue;}
    33                 int tmp=fail[now];
    34                 while(tmp&&!ch[tmp][i]) tmp=fail[tmp];
    35                 fail[to]=ch[tmp][i];
    36                 val[to]|=val[fail[to]];
    37                 q[t++]=to;if(t==200) t=0;
    38             }
    39         }
    40     }
    41 }a;
    42 mat mul(mat &x,mat &y) {
    43     mat ans;
    44     for(int i=0;i<=a.cnt+1;i++)
    45         for(int j=0;j<=a.cnt+1;j++)
    46             for(int k=0;k<=a.cnt+1;k++) ans.f[i][j]+=x.f[i][k]*y.f[k][j];
    47     return ans;
    48 }
    49 mat power(mat x,int c) {
    50     mat ans;
    51     for(int i=0;i<=a.cnt+1;i++) ans.f[i][i]=1;
    52     while(c) {
    53         if(c&1) ans=mul(ans,x);
    54         x=mul(x,x);c>>=1;
    55     }
    56     return ans;
    57 }
    58 void build() {
    59     long double hh=1/(long double)al;
    60     Ans.f[a.cnt+1][a.cnt+1]=1;
    61     for(int i=0;i<=a.cnt;i++) {
    62         if(a.val[i]) continue;
    63         for(int j=0;j<al;j++) {
    64             int to=a.ch[i][j];
    65             if(a.val[to]) {
    66                 Ans.f[a.cnt+1][i]+=hh;
    67                 Ans.f[0][i]+=hh;
    68             }
    69             else Ans.f[to][i]+=hh;
    70         }
    71     }
    72 }
    73 int main() {
    74     scanf("%d%d%d",&n,&m,&al);
    75     for(int i=1;i<=n;i++) {
    76         char s[200];scanf("%s",s+1);
    77         a.build(s);
    78     }
    79     a.getfail();
    80     build();
    81     Ans=power(Ans,m);
    82 /*  for(int i=0;i<=a.cnt+1;i++) {
    83         for(int j=0;j<=a.cnt+1;j++) cout<<Ans.f[i][j]<<' ';
    84         cout<<endl;
    85     }*/
    86      
    87     printf("%.7Lf
    ",Ans.f[a.cnt+1][0]);
    88 }
    89 
    View Code
  • 相关阅读:
    django 开发Broken pipe from ('127.0.0.1', 58078)问题解决
    cocos2d-js中jsc逆向为js攻略
    ECshop 怎样修改商品详细页的“浏览次数”
    ecshop 加广告出现广告位的宽度值必须在1到1024之间
    Nginx 301重定向的配置
    ECSHOP安装百度编辑UEditor教程
    Ecshop商品详情页显示当前会员等级价格
    ECSHOP始终显示全部分类方法
    vps主机修改系统远程端口号/添加防火墙
    ecshop利用.htaccess实现301重定向的方法
  • 原文地址:https://www.cnblogs.com/wls001/p/8550938.html
Copyright © 2020-2023  润新知