题目

一副纸牌有 \(n\) 种,每种有 \(m\) 张,

现在有 \(k\) 个限制条件形如第 \(k_i\) 种牌至少选 \(a_i\) 张,

一个三元组合法当且仅当其为 \((i,i+1,i+2)\) 或 \((i,i,i)\)

现在问有多少种方案使得正好可以分成若干个三元组,

方案不同当且仅当选择的种类不同或数量不同

\(n\leq 10^{18},0\leq k\leq 10^3,0\leq a_i\leq m\leq 10^3\)


分析

考虑三个 \((i,i+1,i+2)\) 可以用 \((i,i,i)\) 和 \((i+1,i+1,i+1)\) 和 \((i+2,i+2,i+2)\) 代替,

所以这样的三元组本质上最多出现两次,设 \(dp[n][i][j]\) 表示

前 \(n\) 个其中 \(i\) 个作为 \((n-1,n,n+1)\),\(j\) 个作为 \((n,n+1,n+2)\) 的方案数。

通过 \(a_n\) 与 \(t=i+j+k\) 的大小分为两种情况,则

\[\large dp[n][i][j]=\sum_{k=0}^2dp[n-1][j][k]+1+\begin{cases}\lfloor\frac{m-t}{3}\rfloor,a_n<t\\\lfloor\frac{m-t-3\lceil\frac{a_n-t}{3}\rceil}{3}\rfloor,otherwise\end{cases}
\]

加一是因为要考虑选完 \(a_n\) 之后不选 \((n,n,n)\) 的情况,

当没有限制条件的时候直接矩阵乘法,否则直接求出转移矩阵相乘即可

最后答案为 \(dp[n][0][0]\)


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int mod=998244353; int m;
struct maix{int p[9][9];}B,A,ANS,U;
typedef long long lll; lll n;
inline lll iut(){
rr lll ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline maix mul(maix A,maix B){
rr maix C;
for (rr int i=0;i<9;++i)
for (rr int j=0;j<9;++j){
C.p[i][j]=0;
for (rr int k=0;k<9;++k)
C.p[i][j]=(C.p[i][j]+1ll*A.p[i][k]*B.p[k][j]%mod)%mod;
}
return C;
}
inline maix ksm(maix A,lll y){
rr maix ANS=U;
for (;y;y>>=1,A=mul(A,A))
if (y&1) ANS=mul(ANS,A);
return ANS;
}
signed main(){
for (rr int i=0;i<9;++i) U.p[i][i]=1;
n=iut(),m=iut(),ANS.p[0][0]=1;
for (rr int i=0;i<3;++i)
for (rr int j=0;j<3;++j)
for (rr int k=0;k<3;++k) if (i+j+k<=m)
A.p[j*3+k][i*3+j]=(m-i-j-k)/3+1;
rr lll lst=0,x,y;
for (rr int Q=iut();Q;--Q,lst=x){
x=iut(),y=iut(),ANS=mul(ANS,ksm(A,x-lst-1));
for (rr int i=0;i<9;++i)
for (rr int j=0;j<9;++j) B.p[i][j]=0;
for (rr int i=0;i<3;++i)
for (rr int j=0;j<3;++j)
for (rr int k=0;k<3;++k){
rr int now=i+j+k;
if (y>=i+j+k) now+=(y-i-j-k+2)/3*3;
if (now<=m) B.p[j*3+k][i*3+j]=(m-now)/3+1;
}
ANS=mul(ANS,B);
}
ANS=mul(ANS,ksm(A,n-lst));
return !printf("%d",ANS.p[0][0]);
}

#dp,矩阵乘法#洛谷 5371 [SNOI2019]纸牌的更多相关文章

  1. 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法

    题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...

  2. 【bzoj3329】Xorequ 数位dp+矩阵乘法

    题目描述 输入 第一行一个正整数,表示数据组数据 ,接下来T行每行一个正整数N 输出 2*T行第2*i-1行表示第i个数据中问题一的解, 第2*i行表示第i个数据中问题二的解, 样例输入 1 1 样例 ...

  3. 洛谷2151[SDOI2009]HH去散步(dp+矩阵乘法优化)

    一道良好的矩阵乘法优化\(dp\)的题. 首先,一个比较\(naive\)的想法. 我们定义\(dp[i][j]\)表示已经走了\(i\)步,当前在点\(j\)的方案数. 由于题目中限制了不能立即走之 ...

  4. BZOJ.1875.[SDOI2009]HH去散步(DP 矩阵乘法)

    题目链接 比较容易想到用f[i][j]表示走了i步后到达j点的方案数,但是题目要求不能走上一条走过的边 如果这样表示是不好转移的 可以考虑边,f[i][j]表示走了i步后到达第j条边的方案数,那么有 ...

  5. 【BZOJ-4386】Wycieczki DP + 矩阵乘法

    4386: [POI2015]Wycieczki Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 197  Solved: 49[Submit][Sta ...

  6. Luogu P4643 【模板】动态dp(矩阵乘法,线段树,树链剖分)

    题面 给定一棵 \(n\) 个点的树,点带点权. 有 \(m\) 次操作,每次操作给定 \(x,y\) ,表示修改点 \(x\) 的权值为 \(y\) . 你需要在每次操作之后求出这棵树的最大权独立集 ...

  7. LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)

    题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...

  8. ZOJ - 3216:Compositions (DP&矩阵乘法&快速幂)

    We consider problems concerning the number of ways in which a number can be written as a sum. If the ...

  9. 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化

    挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...

  10. ZOJ 3256 Tour in the Castle 插头DP 矩阵乘法

    题解 这题是一道非常好的插头题,与一般的按格转移的题目不同,由于m很大,要矩阵乘法,这题需要你做一个按列转移的插头DP. 按列转移多少与按格转移不同,但大体上还是基于连通性进行转移.每一列只有右插头是 ...

随机推荐

  1. 了解企业架构EA(Enterprise Architecture)

    一.企业架构简介 企业架构:Enterprise Architecture,EA,或企业体系结构,是在信息系统架构设计与实践基础上发展起来的一个特殊领域. 但是企业架构现在还没有一个公认的定义,综合现 ...

  2. live555开发笔记(一):live555介绍、windows上msvc2017编译和工程模板

    前言   在pc上搭建流媒体服务器软件,打开视频接受推流,使用live555方案.   live555介绍   Live555是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了标准流媒体传输 ...

  3. XILINX SDK烧录FLASH报错不支持旧版hw_server

    最近频繁遇到SDK报错,说是不支持hw_server旧版本,此时打开vivado识别的时候也是一样报错,可能原因是我电脑安装了多个版本的VIVADO导致的,那么怎么解决呢? 打开任务管理器,kill ...

  4. 【Azure 应用服务】收集App Service 关于Availability Zone, Health check 以及 Traffic Manager的文档,并了解高可用(HA)和灾备(DR)

    问题描述 收集App Service 关于Availability Zone, Health check 以及 Traffic Manager的文档,并了解高可用(HA)和灾备(DR)的具体办法 问题 ...

  5. C++ STL 容器-array类型

    C++ STL 容器-array类型 array是C++11STL封装的数组,内存分配在栈中stack,绝对不会重新分配,随机访问 创建和初始化 // 下面的等同于int a[10]; std::ar ...

  6. uni-app实现公众号登陆实现

    公众号实现登陆流程思路: 1. 创建一个页面用于登陆,页面上需要有输入账号和密码的表单,以及登陆按钮.2. 在登陆按钮的点击事件中,调用后端接口进行账号密码校验.如果校验通过,则将后端返回的用户信息保 ...

  7. MYSQL 是如何保证binlog 和redo log同时提交的?

    MYSQL 一个事务在提交的时候能够保证binlog和redo log是同时提交的,并且能在宕机恢复后保持binlog 和redo log的一致性. 先来看看什么是redo log 和binlog,以 ...

  8. Android Webview判断网页加载完毕

    原文: Android Webview判断网页加载完毕 - Stars-One的杂货小窝 书接上文,在Android WebView获取html源码 - Stars-One的杂货小窝此文讲到没有一个可 ...

  9. Android Studio 下载jcenter依赖失败问题及解决

    优先国内的镜像下载即可 我用的华为和阿里云的国内镜像 google() maven { url 'https://jitpack.io' } maven { url 'http://maven.ali ...

  10. 反转链表——java

    给定一个链表,请你将链表反转过来. 举例:原链表:1→2→3→4→5→null 反转链表:5→4→3→2→1→null 代码: package algorithm_niuke; public clas ...