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

题面

UOJ

洛谷

题解

考虑如何暴力\(dp\)。

设\(f[i][a][b][c]\)表示当前到了第\(i\)次攻击,还剩下的\(1,2,3\)血的奴隶主个数为\(a,b,c\)的概率,每次考虑打到了哪里,做一个转移。

这样子,状态数就是把不超过\(8\)个东西分配到\(3\)个集合中,状态有\(165\)种,再加一个状态记录糊脸上的期望,也就是\(166\)个状态。

直接矩乘优化,那么单次的复杂度就是\(O(166^3*log n)\),显然过不了。

把\(2^k\)的矩阵预处理出来,每次拿行向量去乘矩阵,优化到\(O(166^2*log n)\)

然后就卡卡卡卡卡卡常吧。

提供几个卡常方式:

  • 数组卡着数据范围开
  • 随时交换循环顺序
  • 手动矩乘
  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. #define ll long long
  5. #define MOD 998244353
  6. void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
  7. inline ll read()
  8. {
  9. ll x=0;bool t=false;char ch=getchar();
  10. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  11. if(ch=='-')t=true,ch=getchar();
  12. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  13. return t?-x:x;
  14. }
  15. int m,K;ll n;
  16. int bh[9][9][9],tot,lim[5];
  17. int inv[20];
  18. int P[61][170][170];
  19. int A[170],tmp[170],Ans[170];
  20. void dfs(int a,int b,int c)
  21. {
  22. if(a>lim[1]||b>lim[2]||c>lim[3])return;
  23. if(bh[a][b][c]||a+b+c>K)return;
  24. bh[a][b][c]=++tot;
  25. dfs(a+1,b,c);dfs(a,b+1,c);dfs(a,b,c+1);
  26. }
  27. void Plus(int &A,int &B,int &C){if(m==1)++A;if(m==2)++B;if(m==3)++C;}
  28. void pre()
  29. {
  30. inv[0]=inv[1]=1;for(int i=2;i<20;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
  31. for(int a=0;a<=K&&a<=lim[1];++a)
  32. for(int b=0;a+b<=K&&b<=lim[2];++b)
  33. for(int c=0;a+b+c<=K&&c<=lim[3];++c)
  34. {
  35. int s=a+b+c+1,p=bh[a][b][c];
  36. add(P[0][p][tot+1],inv[s]);add(P[0][p][p],inv[s]);
  37. if(a)P[0][p][bh[a-1][b][c]]=(P[0][p][bh[a-1][b][c]]+1ll*a*inv[s])%MOD;
  38. if(b)
  39. {
  40. int A=a+1,B=b-1,C=c;if(s<=K)Plus(A,B,C);
  41. P[0][p][bh[A][B][C]]=(P[0][p][bh[A][B][C]]+1ll*b*inv[s])%MOD;
  42. }
  43. if(c)
  44. {
  45. int A=a,B=b+1,C=c-1;if(s<=K)Plus(A,B,C);
  46. P[0][p][bh[A][B][C]]=(P[0][p][bh[A][B][C]]+1ll*c*inv[s])%MOD;
  47. }
  48. }
  49. add(P[0][tot+1][tot+1],1);
  50. A[bh[m==1][m==2][m==3]]=1;
  51. for(int p=1;p<=60;++p)
  52. for(int i=1;i<=tot+1;++i)
  53. for(int k=1;k<=tot+1;++k)
  54. for(int j=1;j<=tot+1;++j)
  55. P[p][i][j]=(P[p][i][j]+1ll*P[p-1][i][k]*P[p-1][k][j])%MOD;
  56. }
  57. int main()
  58. {
  59. int T=read();m=read();K=read();
  60. for(int i=1;i<=m;++i)lim[i]=K;
  61. dfs(0,0,0);pre();
  62. while(T--)
  63. {
  64. n=read();int p=0;
  65. for(int i=1;i<=tot+1;++i)Ans[i]=A[i];
  66. while(n)
  67. {
  68. if(n&1)
  69. {
  70. for(int i=1;i<=tot+1;++i)tmp[i]=Ans[i],Ans[i]=0;
  71. for(int k=1;k<=tot+1;++k)
  72. for(int j=1;j<=tot+1;++j)
  73. Ans[j]=(Ans[j]+1ll*tmp[k]*P[p][k][j])%MOD;
  74. }
  75. ++p;n>>=1;
  76. }
  77. printf("%d\n",Ans[tot+1]);
  78. }
  79. return 0;
  80. }

【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)的更多相关文章

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

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

  2. loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主

    #2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较   题目描述 "A fight? Co ...

  3. [清华集训]小 Y 和恐怖的奴隶主

    题面在这里 题意 有一个\(Boss\)和他血量为\(m\)的随从奴隶主,每当奴隶主受到攻击且不死,并且\(Boss\)的随从个数\(<k\)时,就会新召唤一个血量为\(m\)的奴隶主.每次攻击 ...

  4. 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法

    题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...

  5. uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵加速)

    传送门 uoj上的数据太毒了--也可能是我人傻常数大的缘故-- 三种血量的奴隶主加起来不超过\(8\)个,可以枚举每种血量的奴隶主个数,那么总的状态数只有\(165\)种,设\(dp_{t,i,j,k ...

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

    传送门 一道不错的矩阵快速幂优化dpdpdp. 设f[i][j][k][l]f[i][j][k][l]f[i][j][k][l]表示前iii轮第iii轮还有jjj个一滴血的,kkk个两滴血的,lll个 ...

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

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

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

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

  9. LOJ2325「清华集训 2017」小Y和恐怖的奴隶主

    题目链接 首先dp很显然,\(f(i,s)\)表示到了第i轮,各种血量人数的情况为s今后的期望攻击boss次数.那么有\(f(i,s)=\frac{1}{num+1}*\sum_{s->s'}( ...

随机推荐

  1. tortoisegit密钥与git密钥配置

    在客户端生成密钥并将公钥上传到服务器可以避免每次连接git服务器都要登录的尴尬. 但git的私钥是不能直接用在tortoisegit上的,需要用tortoisegit的puttygen转换一下,详细过 ...

  2. JS_左边栏菜单

    需求: 要求实现左边栏菜单点击一下就弹开,其他的隐藏.再点击一下就隐藏. 最多只能有一个菜单的详细内容会显示出来. 三个菜单实现联动效果. 代码如下: 1 <!DOCTYPE html> ...

  3. hadoop和java 配置环境变量的的tar

    第一步:打开工具上传tar包 如下图 第二步:在文件路径下查看是否上传成功 第三步:解压tar包               tar -zxvf hadoop.2.6.5.tar.gz 第四步:配置环 ...

  4. windows下linux子系统安装

    1.打开Windows功能中的使用于linux的Windows子系统 2.应用商店中下载需要的linux 3.下载完成后运行等待安装并输入用户名密码  4.查看系统信息 先后 sudo apt-get ...

  5. Java中有关Null的9件事(转)

    对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...

  6. [转帖]Linux分页机制之分页机制的演变--Linux内存管理(七)

    Linux分页机制之分页机制的演变--Linux内存管理(七) 2016年09月01日 20:01:31 JeanCheng 阅读数:4543 https://blog.csdn.net/gatiem ...

  7. [转帖]国产紫光SSD不再只是实验室展品 开始批量出货

    国产紫光SSD不再只是实验室展品 开始批量出货 https://www.cnbeta.com/articles/tech/825865.htm 没听说有做HDD的 现做了SSD 弯道超车吗 可以实现全 ...

  8. CSS实现元素水平垂直居中

    我们知道,实现元素的水平居中比较简单,在设置了宽度后,设置左右margin为auto就可以. 但是如何设置元素垂直居中呢? 当然,对于单行的文字,可以通过设置line-height来解决, 可以对于一 ...

  9. 从 Aliyun 经典网络迁移到 Aliyun VPC 网络

    由于阿里云策略问题,要求用户从经典网络中全部迁出,搬迁到他们设置的 VPC 网络中.这里的 VPC 大概指的是逻辑上的一个虚拟局域网.即使是实际上你的机器垮机房在阿里云的不同机房.但是他们仍然能从逻辑 ...

  10. Golang的select多路复用以及channel使用实践

    看到有个例子实现了一个类似于核弹发射装置,在发射之前还是需要随时能输入终止发射. 这里就可以用到cahnnel 配合select 实现多路复用. select的写法用法有点像switch.但是和swi ...