首页 > 其他分享 >矩阵乘法(快速幂)结合dp结合除法逆元的例题

矩阵乘法(快速幂)结合dp结合除法逆元的例题

时间:2022-10-04 23:45:40浏览次数:54  
标签:23 res LL fore 逆元 base 例题 dp MOD

https://atcoder.jp/contests/abc271/tasks/abc271_g

题目的思路为:

构建dp矩阵,dp[i][j][k]表示开始前停在j,结束后停在k,且停下时恰好出现2^i次访问的概率

则dp[i]=dp[i-1]*dp[i-1]

(矩阵乘法的中间过程模拟的就是两个2^(i-1)次访问的中间停靠点,矩阵乘法中间的求和就是将不同中间过程的概率求和)

然后可以用快速幂的形式,求解访问n次的概率矩阵。

注意到,除法逆元按直觉写即可,一般都可以得到正确的答案。

代码:

#include<bits/stdc++.h>
using namespace std;
using LL = long long;

#define fore(x,y,z) for(LL x=(y);x<=(z);x++)
#define forn(x,y,z) for(LL x=(y);x<(z);x++)
#define rofe(x,y,z) for(LL x=(y);x>=(z);x--)
#define rofn(x,y,z) for(LL x=(y);x>(z);x--)
#define fi first
#define se second
LL n;
int x, y;
const int N = 24;
LL base[N][N];
LL res[N][N];
string str;
LL MOD = 998244353;
void Mul(LL m1[N][N], LL m2[N][N])
{
    LL res[N][N] = { 0 };
    fore(i, 0, 23)
    {
        fore(j, 0, 23)
        {
            fore(k, 0, 23)
            {
                res[i][j] += m1[i][k] * m2[k][j];
                res[i][j] %= MOD;
            }
        }
    }
    fore(i, 0, 23)
    {
        fore(j, 0, 23)
        {
            m1[i][j] = res[i][j];
        }
    }
}
LL QuickExp(LL base, LL exp)
{
    LL res = 1;
    while (exp)
    {
        if (exp & 1)
        {
            res *= base;
            res %= MOD;
        }
        base *= base;
        base %= MOD;
        exp >>= 1;
    }
    return res;
}
LL Inv(LL num)
{
    return QuickExp(num, MOD - 2);
}
LL QuickExp()
{
    fore(i, 0, 23) res[i][i] = 1;
    fore(i, 0, 23)
    {
        fore(j, 0, 23)
        {
            LL tmp = 1;
            int k = i + 1;
            k %= 24;
            LL p = 1;
            while (1)
            {
                if (k == j)
                {
                    LL up;
                    if (str[k] == 'T') up = x;
                    else up = y;
                    LL down = 100;
                    p = p * up%MOD*Inv(down) % MOD;
                    break;
                }
                else
                {
                    LL up;
                    if (str[k] == 'T') up = 100 - x;
                    else up = 100 - y;
                    LL down = 100;
                    p = p * up%MOD*Inv(down) % MOD;
                }
                k++;
                k %= 24;
            }
            LL q = 1;
            fore(i, 0, 23)
            {
                LL up;
                if (str[i] == 'T') up = 100 - x;
                else up = 100 - y;
                LL down = 100;
                q = q * up%MOD*Inv(down) % MOD;
            }
            tmp = (p * Inv(1 - q) % MOD + MOD) % MOD;
            base[i][j] = tmp;
        }
    }
    while (n)
    {
        if (n & 1)
        {
            Mul(res, base);
        }
        Mul(base, base);
        n >>= 1;
    }
    LL ans = 0;
    fore(i, 0, 23)
    {
        if (str[i] == 'A')
        {
            ans += res[23][i];
            ans %= MOD;
        }
    }
    return ans;

}
int main()
{
    cin >> n >> x >> y;

    cin >> str;
    cout << QuickExp() << endl;
}
View Code

 

标签:23,res,LL,fore,逆元,base,例题,dp,MOD
From: https://www.cnblogs.com/ydUESTC/p/16754860.html

相关文章

  • SV学习(3)——接口interface、modport、时钟块clocking
    SV学习(3)——接口interface、modport、时钟块clocking1.接口interface2.modport3.时钟块clocking3.1.驱动和采用的竞争问题3.2.clocking待补充....=====......
  • 线性DP-2430. 对字母串可执行的最大删除数
    问题描述给你一个仅由小写英文字母组成的字符串s。在一步操作中,你可以:删除整个字符串s,或者对于满足 1<=i<=s.length/2的任意i,如果s中的前i个字母和......
  • dp----在一些意想不到的地方用到了dp
    《题一:SubsequencePath》原题链接:https://atcoder.jp/contests/abc271/tasks/abc271_e原题详细题解:https://atcoder.jp/contests/abc271/editorial/4940题目大意:有......
  • TCP与UDP的联系与区别
    UDP(UserDataProtocol,用户数据报协议)1、UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网......
  • DP专题
    分治优化DP分治优化1D/1Ddp对于一类\[f(x)=\min_{k=y}^{x-1}w(l,r)\]即所有\(w(l,r)\)事先已知,且\(f(x)\)满足决策单调性(即\(w(l,r)\)满足区间包含单......
  • 数位DP
    Acwing338.计数问题给定两个整数 aa 和 bb,求 aa 和 bb 之间的所有数字中 0∼90∼9 的出现次数。例如,a=1024,b=1032a=1024,b=1032,则 aa 和 bb 之间共有 99......
  • 「CF1455G」Forbidden Value 题解 (DP,线段树合并)
    题目简介已知初始值\(x=0\),给定下面\(2\)种命令:set\(y\)\(v\),令\(x=y\),或花费\(v\)元钱删除该命令;if\(y\)...end,如果\(x==y\),执行if...end中的命令,否则跳......
  • C# UdpClient发送超过1500字节MTU的数据包会怎么样
    如果不设置DontFragmentudpClient.DontFragment=false;那么可以发送数据包。接收端随缘收到数据包。使用WireShark可以检测到网卡上对应的数据包。如果设置DontFragm......
  • P5431 【模板】乘法逆元 2
    1#include<bits/stdc++.h>2usingnamespacestd;3typedeflonglongll;4constintN=5e6+10;5llfac[N],sv[N],inv[N],a[N];6lln,p,k;7v......
  • UDP程序设计
    UDP程序设计​无连接,不可靠的数据报协议-->简单,快捷域名系统,简单网络管理协议(SNMP),网络文件系统(NFS),动态主机配置协议(DHCP),实时传输协议RTP服务器端:创建socket......