LINK


思路

首先是考虑怎么设计dp的状态

发现奴隶主的顺序没有影响,只有生命和个数有影响,所以就可以把每个生命值的奴隶主有多少压缩成状态就可以了

然后发现无论是什么时候一个状态到另一个状态的转移都是固定的方式

所以可以预处理转移矩阵用矩阵快速幂进行优化

但是如果在计算的时候暴力\(状态^3\)进行转移会TLE

但是注意到在这个时候有用的状态其实只有一个向量

所以就预处理倍增然后用向量乘矩阵来优化到单次\(logn状态^2\)就可以了

有点卡常


  1. //Author: dream_maker
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. //----------------------------------------------
  5. //typename
  6. typedef long long ll;
  7. //convenient for
  8. #define fu(a, b, c) for (int a = b; a <= c; ++a)
  9. #define fd(a, b, c) for (int a = b; a >= c; --a)
  10. #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
  11. //inf of different typename
  12. const int INF_of_int = 1e9;
  13. const ll INF_of_ll = 1e18;
  14. //fast read and write
  15. template <typename T>
  16. void Read(T &x) {
  17. bool w = 1;x = 0;
  18. char c = getchar();
  19. while (!isdigit(c) && c != '-') c = getchar();
  20. if (c == '-') w = 0, c = getchar();
  21. while (isdigit(c)) x = (x<<1) + (x<<3) + c -'0', c = getchar();
  22. if (!w) x = -x;
  23. }
  24. template <typename T>
  25. void Write(T x) {
  26. if (x < 0) putchar('-'), x = -x;
  27. if (x > 9) Write(x / 10);
  28. putchar(x % 10 + '0');
  29. }
  30. //----------------------------------------------
  31. const int N = 170;
  32. const int Mod = 998244353;
  33. ll n, m, K, cnt = 0;
  34. int inv[10];
  35. int id[9][9][9];
  36. struct Matrix{
  37. int t[N][N];
  38. Matrix() { memset(t, 0, sizeof(t));}
  39. }trans, g[61];
  40. inline int add(int a, int b) { return ((a += b) > Mod) ? (a - Mod) : a; }
  41. inline int mul(int a, int b) { return 1ll * a * b % Mod; }
  42. Matrix operator * (const Matrix a, const Matrix b) {
  43. Matrix c;
  44. fu(k, 0, cnt)
  45. fu(i, 0, cnt) if (a.t[i][k])
  46. fu(j, 0, cnt)
  47. c.t[i][j] = add(c.t[i][j], mul(a.t[i][k], b.t[k][j]));
  48. return c;
  49. }
  50. inline Matrix mul_matrix(Matrix a, Matrix b) {
  51. Matrix c;
  52. fu(k, 0, cnt) if(a.t[0][k])
  53. fu(j, 0, cnt)
  54. c.t[0][j] = add(c.t[0][j], mul(a.t[0][k], b.t[k][j]));
  55. return c;
  56. }
  57. inline int fast_pow(int a, int b) {
  58. int ans = 1;
  59. while (b) {
  60. if (b & 1) ans = mul(ans, a);
  61. b >>= 1;
  62. a = mul(a, a);
  63. }
  64. return ans;
  65. }
  66. inline int get_add_id(int i, int j, int k) {
  67. if (i + j + k == K) return id[i][j][k];
  68. if (m == 1) return id[i + 1][j][k];
  69. if (m == 2) return id[i][j + 1][k];
  70. if (m == 3) return id[i][j][k + 1];
  71. }
  72. void init() {
  73. fu(i, 1, K + 1)inv[i] = fast_pow(i, Mod - 2);
  74. int upj, upk, ID, inv_sum;
  75. fu(i, 0, K) {
  76. upj = (m == 1)? 0 : K - i;
  77. fu(j, 0, upj) {
  78. upk = (m == 2)? 0 : K - i - j;
  79. fu(k, 0, upk) id[i][j][k] = ++cnt;
  80. }
  81. }
  82. ++cnt;
  83. trans.t[cnt][cnt] = 1;
  84. fu(i, 0, K) {
  85. upj = (m == 1)? 0 : K - i;
  86. fu(j, 0, upj) {
  87. upk = (m == 2)? 0 : K - i - j;
  88. fu(k, 0, upk) {
  89. ID = id[i][j][k], inv_sum = inv[i + j + k + 1];
  90. if (i) trans.t[ID][id[i - 1][j][k]] = mul(inv_sum, i);
  91. if (j) trans.t[ID][get_add_id(i + 1, j - 1, k)] = mul(inv_sum, j);
  92. if (k) trans.t[ID][get_add_id(i, j + 1, k - 1)] = mul(inv_sum, k);
  93. trans.t[ID][ID] = trans.t[ID][cnt] = inv_sum;
  94. }
  95. }
  96. }
  97. g[0] = trans;
  98. fu(i, 1, 60) g[i] = g[i - 1] * g[i - 1];
  99. }
  100. int main() {
  101. #ifdef dream_maker
  102. freopen("input.txt","r",stdin);
  103. #endif
  104. int T;Read(T);
  105. Read(m); Read(K);
  106. init();
  107. int pre = get_add_id(0, 0, 0);
  108. while (T--) {
  109. Read(n);
  110. Matrix ans;
  111. ans.t[0][pre] = 1;
  112. fu(i, 0, 60)
  113. if ((n >> i) & 1) ans = mul_matrix(ans, g[i]);
  114. printf("%d\n", ans.t[0][cnt]);
  115. }
  116. return 0;
  117. }

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

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

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

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

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

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

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

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

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

  5. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  6. [LOJ#2324]「清华集训 2017」小Y和二叉树

    [LOJ#2324]「清华集训 2017」小Y和二叉树 试题描述 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙 ...

  7. [LOJ#2323]「清华集训 2017」小Y和地铁

    [LOJ#2323]「清华集训 2017」小Y和地铁 试题描述 小Y是一个爱好旅行的OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的 ...

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

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

  9. loj2324 「清华集训 2017」小 Y 和二叉树

    https://loj.ac/problem/2324 太智障,一开始以为中序遍历的第一个点一定是一个叶子,想了个贪心.然而,手算了一下,第一个点都过不了啊. input 5 2 3 4 1 3 3 ...

随机推荐

  1. .net知识点汇总

    死锁的必要条件?怎么克服? 答:系统的资源不足,进程的推进的顺序不合适,资源分配不当,一个资源每次只能被一个进程使用,一个资源请求资源时,而此时这个资源已阻塞,对已获得资源不放,进程获得资源时,未使用 ...

  2. phpcms v9 栏目伪静态完全自定义为栏目英文目录名

    1,后台增加url规则,增加后.导航上,或分页号上,会自动替换为静态的样式.类似www.abc.com/news/2/ 2表示页码 phpcms v9 的后台扩展,url规则,添加两个规则, 一个是名 ...

  3. flask学习(四):debug模式

    一. 设置debug模式 1. flask 1.0之前 在app.run()中传入一个关键字参数debug,app.run(debug=True),就设置当前项目为debug模式 2. flask 1 ...

  4. IOS-2016年最好的15个Web设计和开发工具

    设计师和开发者,web设计师和开发者遍地开花.这促使web开发人员也需要寻找最好的工具去设计出优于其他人的网站.作为一个web设计师或开发者,你必须寻找新的途径来提高自己的技能,提高自己的工作质量.下 ...

  5. 尝试优化骨骼动画计算的意外收获——使用嵌入式汇编对float转int进行优化

    本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4984530.html 公司引擎目前是使用CPU计算骨骼动画(采用了D3DX提供的函数 ...

  6. ios 不兼容 报错NaN

    function GetDateDiff(DiffTime) { //将xxxx-xx-xx的时间格式,转换为 xxxx/xx/xx的格式 Time = DiffTime.replace(/\-/g, ...

  7. C# ASP.NET 验证码

    使用C# ASP.NET 获取 验证码的代码书写 一般都采用异步 点击 前台验证码图片 请求一次 : 前台图片代码: <img id="imgvalidatecode" sr ...

  8. Java常用类:StringBuilder

    一.介绍 2 3 4 5 //同样,StringBuilder也是final修饰的不可变,相比String来说,继承了AbstractStringBuilder,StringBuffer也是同样继承了 ...

  9. Java虚拟机访问读写其他进程的数据--RandomAccessFile

    RandomAccessFile 是Java输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据.并且它支持“任意访问”的方式,程 ...

  10. c# excel转换为DataTable

    System.Data.DataTable GetDataFromExcelByCom(bool hasTitle, string fileName) { //OpenFileDialog openF ...