• 后宫


    [Description]
    山山是 2017 级信奥班的成员,因为良好(到大家都嫉妒的程度)的妹子缘而出名。山
    山认识的妹子实在是太多,信奥班的各位纷纷猜测山山是怎么做到的。终于,Gemin 揭开了
    这个秘密。原来,山山掌握了向妹子脑中写入程序的黑科技。山山向妹子脑中写入的程序是
    一个只含有“N”、
    “H”两种大写字母的字符串,每个大写字母代表一条指令;指令顺序执
    行,并且在执行到结尾后立即返回起始位置,依此无限循环。每条指令都耗费一个指令周期
    执行。
    两种指令的含义如下:
    “N”
    :什么都不做;
    “H”
    :执行到这条指令的妹子 A 会找到一个新的妹子 B,并在妹子 B 的大脑中写入同一段
    程序。在下一个指令周期开始时,妹子 B 会加入山山的后宫,并立即开始执行程序。
    现在,山山的后宫中只有一个妹子 Eve,在第一个指令周期开始时,Eve 会从头开始执
    行程序。现在请计算,在第 N 个指令周期结束时,山山的后宫里有多少妹子。为了避免答
    案过大,请输出答案模上 998244353 的值。
    [Input]
    第一行一个整数:N。
    下面一行,一个长度为 L 的、只含有“N”、“H”两种大写字母的字符串 S、代表山山会
    在妹子的大脑里写入的程序。
    [Output]
    一行一个整数,代表在第 N 个指令周期结束时,山山的后宫里有多少妹子。
    [Sample]


    说明:什么都不做......


    说明:虽然在第二个周期中,Eve 找到了一个新的妹子,但是新的妹子直到第三个周期的开
    始才会加入后宫,因此第二个周期结束时仍然只有一个妹子。


    [Tips]

    使用 dp[i][j] 代表在第 i 个指令周期中,执行第 j 条指令的妹子的数量。用转出型的
    转移。
    dp[i][j] 可以转移到 dp[i + 1][(j + 1) % L] ,当第 j 条指令是“ H” 时,也能转移到
    dp[i + 1][0] 。观察发现 dp[i] 可以表示为 1 x L 的矩阵, dp[i] 和 dp[i + 1] 之间的转移可
    以表示为边长为 L 的方阵,因此使用矩阵乘法优化即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long lol;
     7 struct Matrix
     8 {
     9   lol a[51][51];
    10 }ans,Mat;
    11 lol n,sum,Mod=998244353,l,anss;
    12 char s[100005];
    13 Matrix operator*(const Matrix x,const Matrix y)
    14 {int i,j,k;
    15   Matrix res;
    16   memset(res.a,0,sizeof(res.a));
    17   for (i=1;i<=l;i++)
    18     for (j=1;j<=l;j++)
    19       for (k=1;k<=l;k++)
    20     res.a[i][j]+=x.a[i][k]*y.a[k][j]%Mod,res.a[i][j]%=Mod;
    21   return res;
    22 }
    23 Matrix qpow(lol y)
    24 {int i;
    25   Matrix res;
    26   for (i=1;i<=l;i++)
    27     res.a[i][i]=1;
    28   while (y)
    29     {
    30       if (y&1) res=res*Mat;
    31       Mat=Mat*Mat;
    32       y/=2;
    33     }
    34   return res;
    35 }
    36 int main()
    37 {int i;
    38   cin>>n;
    39   cin>>s;
    40   l=strlen(s);
    41   for (i=0;i<l;i++)
    42     if (s[i]=='H') Mat.a[i+1][1]++;
    43   Mat.a[l][1]++;
    44   for (i=2;i<=l;i++)
    45     Mat.a[i-1][i]=1;
    46   ans.a[1][1]=1;
    47   Mat=qpow(n-1);
    48   ans=ans*Mat;
    49   for (i=1;i<=l;i++)
    50     anss+=ans.a[1][i],anss%=Mod;
    51   cout<<anss;
    52 }
  • 相关阅读:
    点分治练习
    PKU-2723 Get Luffy Out(2-SAT+二分)
    tarjan求割点与割边
    tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows
    数算日子荣耀神
    《JavaScript DOM编程艺术》笔记
    CSS链接的样式a:link,a:visited,a:hover,a:active
    chrome调试技巧--持续更新
    CSS文字大小单位PX、EM的区别
    【转】如何成为一名优秀的web前端工程师(前端攻城师)?
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7699355.html
Copyright © 2020-2023  润新知