传送门

一道不错的矩阵快速幂优化dpdpdp。

设f[i][j][k][l]f[i][j][k][l]f[i][j][k][l]表示前iii轮第iii轮还有jjj个一滴血的,kkk个两滴血的,lll个三滴血的。

显然是可以从f[i−1]f[i-1]f[i−1]转移过来的。

但是仔细一想,这个递推关系在i=1i=1i=1~nnn的时候都是一样的,于是把后面三个状压上矩阵快速幂优化就行了。

直接转是O(T∗size3log)O(T*size^3log)O(T∗size3log)的。

于是可以用倍增的思想预处理出logloglog个数组,最后乘起来,由于结构相同可以做到O(size∗size∗logn∗T+size∗size∗size∗logn)O(size*size*log_n*T+size*size*size*log_n)O(size∗size∗logn​∗T+size∗size∗size∗logn​)

注意卡常优化。

代码:

  1. #include<bits/stdc++.h>
  2. #define Len 170
  3. #define mod 998244353
  4. #define ll unsigned long long
  5. using namespace std;
  6. int T,m,K,id[15][15][15],tot=0;
  7. ll inv[15],ans[Len],n,tmp[Len];
  8. const ll inf=16940360401038606353llu;
  9. inline ll read(){
  10. ll ans=0;
  11. char ch=getchar();
  12. while(!isdigit(ch))ch=getchar();
  13. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  14. return ans;
  15. }
  16. inline void write(const ll&x){
  17. if(x>9)write(x/10);
  18. putchar((x-x/10*10)^48);
  19. }
  20. struct Matrix{
  21. ll val[Len][Len];
  22. inline void init(){memset(val,0,sizeof(val));}
  23. }f[65];
  24. inline Matrix operator*(const Matrix&a,const Matrix&b){
  25. Matrix ret;
  26. ret.init();
  27. for(int i=1;i<=tot+1;++i)for(int k=1;k<=tot+1;++k)
  28. for(int j=1;j<=tot+1;++j){{
  29. ret.val[i][j]+=a.val[i][k]*b.val[k][j];
  30. if(ret.val[i][j]>=inf)ret.val[i][j]-=inf;
  31. }
  32. }
  33. for(int i=1;i<=tot+1;++i)for(int j=1;j<=tot+1;++j)ret.val[i][j]%=mod;
  34. return ret;
  35. }
  36. inline void update(const Matrix&a){
  37. memset(tmp,0,sizeof(tmp));
  38. for(int i=1;i<=tot+1;++i){
  39. for(int j=1;j<=tot+1;++j){
  40. tmp[i]+=ans[j]*a.val[j][i];
  41. if(tmp[i]>=inf)tmp[i]-=inf;
  42. }
  43. tmp[i]%=mod;
  44. }
  45. memcpy(ans,tmp,sizeof(tmp));
  46. }
  47. int main(){
  48. T=read(),m=read(),K=read(),inv[0]=inv[1]=1;
  49. for(int i=2;i<=10;++i)inv[i]=(mod-mod/i)*inv[mod%i]%mod;
  50. for(int i=0;i<=K;++i)for(int j=0;j<=(m>1?K-i:0);++j)for(int k=0;k<=(m>2?K-i-j:0);++k)id[i][j][k]=++tot;
  51. for(int i=0;i<=K;++i)for(int j=0;j<=(m>1?K-i:0);++j)for(int k=0;k<=(m>2?K-i-j:0);++k){
  52. int pos=id[i][j][k],t=(i+j+k)<K;
  53. if(m==1)if(i)f[0].val[pos][id[i-1][j][k]]=inv[i+1]*i%mod;
  54. if(m==2){
  55. if(i)f[0].val[pos][id[i-1][j][k]]=inv[i+j+1]*i%mod;
  56. if(j)f[0].val[pos][id[i+1][j+t-1][k]]=inv[i+j+1]*j%mod;
  57. }
  58. if(m==3){
  59. if(i)f[0].val[pos][id[i-1][j][k]]=inv[i+j+k+1]*i%mod;
  60. if(j)f[0].val[pos][id[i+1][j-1][k+t]]=inv[i+j+k+1]*j%mod;
  61. if(k)f[0].val[pos][id[i][j+1][k+t-1]]=inv[i+j+k+1]*k%mod;
  62. }
  63. f[0].val[pos][pos]=f[0].val[pos][tot+1]=inv[i+j+k+1];
  64. }
  65. f[0].val[tot+1][tot+1]=1;
  66. for(int i=1;i<=63;++i)f[i]=f[i-1]*f[i-1];
  67. while(T--){
  68. n=read(),memset(ans,0,sizeof(ans));
  69. switch(m){
  70. case 1:ans[id[1][0][0]]=1;break;
  71. case 2:ans[id[0][1][0]]=1;break;
  72. case 3:ans[id[0][0][1]]=1;break;
  73. }
  74. for(int i=0;n;n>>=1,++i)if(n&1)update(f[i]);
  75. write(ans[tot+1]),puts("");
  76. }
  77. return 0;
  78. }

2018.10.16 uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂优化dp)的更多相关文章

  1. 2018.10.22 bzoj1009: [HNOI2008]GT考试(kmp+矩阵快速幂优化dp)

    传送门 f[i][j]f[i][j]f[i][j]表示从状态"匹配了前i位"转移到"匹配了前j位"的方案数. 这个东西单次是可以通过跳kmp的fail数组得到的 ...

  2. LOJ2325. 「清华集训 2017」小 Y 和恐怖的奴隶主【矩阵快速幂优化DP】【倍增优化】

    LINK 思路 首先是考虑怎么设计dp的状态 发现奴隶主的顺序没有影响,只有生命和个数有影响,所以就可以把每个生命值的奴隶主有多少压缩成状态就可以了 然后发现无论是什么时候一个状态到另一个状态的转移都 ...

  3. LibreOJ #2325. 「清华集训 2017」小Y和恐怖的奴隶主(矩阵快速幂优化DP)

    哇这题剧毒,卡了好久常数才过T_T 设$f(i,s)$为到第$i$轮攻击,怪物状态为$s$时对boss的期望伤害,$sum$为状态$s$所表示的怪物个数,得到朴素的DP方程$f(i,s)=\sum \ ...

  4. [清华集训2017]小 Y 和地铁(神奇思路,搜索,剪枝,树状数组)

    世界上最不缺的就是好题. 首先考虑暴搜.(还有什么题是从这东西推到正解的……) 首先单独一个换乘站明显没用,只用考虑一对对的换乘站. 那么有八种情况:(从题解偷图)         然后大力枚举每个换 ...

  5. 2018.10.23 bzoj1297: [SCOI2009]迷路(矩阵快速幂优化dp)

    传送门 矩阵快速幂优化dp简单题. 考虑状态转移方程: f[time][u]=∑f[time−1][v]f[time][u]=\sum f[time-1][v]f[time][u]=∑f[time−1 ...

  6. 2018.10.19 NOIP模拟 硬币(矩阵快速幂优化dp)

    传送门 不得不说神仙出题人DZYODZYODZYO出的题是真的妙. f[i][j][k]f[i][j][k]f[i][j][k]表示选的硬币最大面值为iii最小面值不小于jjj,总面值为kkk时的选法 ...

  7. 2018.11.08 NOIP模拟 景点(倍增+矩阵快速幂优化dp)

    传送门 首先按照题意构造出转移矩阵. 然后可以矩阵快速幂求出答案. 但是直接做是O(n3qlogm)O(n^3qlogm)O(n3qlogm)的会TTT掉. 观察要求的东西发现我们只关系一行的答案. ...

  8. 【六省联考2017】组合数问题 题解(矩阵快速幂优化DP)

    题目链接 题目大意:求$(\sum\limits_{i=0}^n C_{nk}^{ik+r})\ mod \ p$的值. --------------------- 讲真,一开始看到这个题我都没往DP ...

  9. 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)

    [UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...

随机推荐

  1. IE6部分兼容问题

    border-style:dotted 点线 IE6不兼容 (除了solid以外,其它都有兼容问题,不完全一样) a IE6 不支持a以外的所有标签伪类,IE6以上版本支持所有标签的hover伪类. ...

  2. sftp(paramiko)

    SFTP同样是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的.但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用S ...

  3. Mongodb 安装 和 启动

    教程:http://www.mongodb.org.cn/tutorial/59.html 下载 >wget https://fastdl.mongodb.org/linux/mongodb-l ...

  4. SpringBoot 监控管理模块actuator没有权限的问题

    SpringBoot 1.5.9 版本加入actuator依赖后, 访问/beans 等敏感的信息时候报错,如下 Tue Mar 07 21:18:57 GMT+08:00 2017 There wa ...

  5. sql查询分析器中显示行号

    -- 工具-> -- 选项-> -- 文本编辑器-> -- 所有语言-> -- 常规-> -- 显示-> -- 行号

  6. Hibernate hql 多表查询

    String hql="select c from Col c ,UserRole role where c.id=role.columnId and c.id=? and role.use ...

  7. lzo文件压缩,解压

    LZOP命令安装 yum install lzop lzop命令基本操作命令 # lzop -v test # 创建test.lzo压缩文件,输出详细信息,保留test文件不变 # lzop -Uv ...

  8. 在SQL Server中使用CLR调用.NET方法

    介绍    我们一起来做个示例,在.NET中新建一个类,并在这个类里新建一个方法,然后在SQL Server中调用这个方法.按照微软所述,通过宿主 Microsoft .NET Framework 2 ...

  9. 正则表达式在JS中的使用

    <script type="text/javascript"> /** *正则表达式在js中的第一种使用方式: * RegExp 通过构造器去使用正则表达式 需要对反斜 ...

  10. sar命令详细信息

    sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况.系统调用的使用情 ...