【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)
【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)
题面
题解
考虑如何暴力\(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)\)
然后就卡卡卡卡卡卡常吧。
提供几个卡常方式:
- 数组卡着数据范围开
- 随时交换循环顺序
- 手动矩乘
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
#define MOD 998244353
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
inline ll read()
{
ll x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int m,K;ll n;
int bh[9][9][9],tot,lim[5];
int inv[20];
int P[61][170][170];
int A[170],tmp[170],Ans[170];
void dfs(int a,int b,int c)
{
if(a>lim[1]||b>lim[2]||c>lim[3])return;
if(bh[a][b][c]||a+b+c>K)return;
bh[a][b][c]=++tot;
dfs(a+1,b,c);dfs(a,b+1,c);dfs(a,b,c+1);
}
void Plus(int &A,int &B,int &C){if(m==1)++A;if(m==2)++B;if(m==3)++C;}
void pre()
{
inv[0]=inv[1]=1;for(int i=2;i<20;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int a=0;a<=K&&a<=lim[1];++a)
for(int b=0;a+b<=K&&b<=lim[2];++b)
for(int c=0;a+b+c<=K&&c<=lim[3];++c)
{
int s=a+b+c+1,p=bh[a][b][c];
add(P[0][p][tot+1],inv[s]);add(P[0][p][p],inv[s]);
if(a)P[0][p][bh[a-1][b][c]]=(P[0][p][bh[a-1][b][c]]+1ll*a*inv[s])%MOD;
if(b)
{
int A=a+1,B=b-1,C=c;if(s<=K)Plus(A,B,C);
P[0][p][bh[A][B][C]]=(P[0][p][bh[A][B][C]]+1ll*b*inv[s])%MOD;
}
if(c)
{
int A=a,B=b+1,C=c-1;if(s<=K)Plus(A,B,C);
P[0][p][bh[A][B][C]]=(P[0][p][bh[A][B][C]]+1ll*c*inv[s])%MOD;
}
}
add(P[0][tot+1][tot+1],1);
A[bh[m==1][m==2][m==3]]=1;
for(int p=1;p<=60;++p)
for(int i=1;i<=tot+1;++i)
for(int k=1;k<=tot+1;++k)
for(int j=1;j<=tot+1;++j)
P[p][i][j]=(P[p][i][j]+1ll*P[p-1][i][k]*P[p-1][k][j])%MOD;
}
int main()
{
int T=read();m=read();K=read();
for(int i=1;i<=m;++i)lim[i]=K;
dfs(0,0,0);pre();
while(T--)
{
n=read();int p=0;
for(int i=1;i<=tot+1;++i)Ans[i]=A[i];
while(n)
{
if(n&1)
{
for(int i=1;i<=tot+1;++i)tmp[i]=Ans[i],Ans[i]=0;
for(int k=1;k<=tot+1;++k)
for(int j=1;j<=tot+1;++j)
Ans[j]=(Ans[j]+1ll*tmp[k]*P[p][k][j])%MOD;
}
++p;n>>=1;
}
printf("%d\n",Ans[tot+1]);
}
return 0;
}
【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)的更多相关文章
- [清华集训2017]小 Y 和地铁(神奇思路,搜索,剪枝,树状数组)
世界上最不缺的就是好题. 首先考虑暴搜.(还有什么题是从这东西推到正解的……) 首先单独一个换乘站明显没用,只用考虑一对对的换乘站. 那么有八种情况:(从题解偷图) 然后大力枚举每个换 ...
- loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主
#2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 "A fight? Co ...
- [清华集训]小 Y 和恐怖的奴隶主
题面在这里 题意 有一个\(Boss\)和他血量为\(m\)的随从奴隶主,每当奴隶主受到攻击且不死,并且\(Boss\)的随从个数\(<k\)时,就会新召唤一个血量为\(m\)的奴隶主.每次攻击 ...
- 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法
题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...
- uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵加速)
传送门 uoj上的数据太毒了--也可能是我人傻常数大的缘故-- 三种血量的奴隶主加起来不超过\(8\)个,可以枚举每种血量的奴隶主个数,那么总的状态数只有\(165\)种,设\(dp_{t,i,j,k ...
- 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个 ...
- LibreOJ #2325. 「清华集训 2017」小Y和恐怖的奴隶主(矩阵快速幂优化DP)
哇这题剧毒,卡了好久常数才过T_T 设$f(i,s)$为到第$i$轮攻击,怪物状态为$s$时对boss的期望伤害,$sum$为状态$s$所表示的怪物个数,得到朴素的DP方程$f(i,s)=\sum \ ...
- LOJ2325. 「清华集训 2017」小 Y 和恐怖的奴隶主【矩阵快速幂优化DP】【倍增优化】
LINK 思路 首先是考虑怎么设计dp的状态 发现奴隶主的顺序没有影响,只有生命和个数有影响,所以就可以把每个生命值的奴隶主有多少压缩成状态就可以了 然后发现无论是什么时候一个状态到另一个状态的转移都 ...
- LOJ2325「清华集训 2017」小Y和恐怖的奴隶主
题目链接 首先dp很显然,\(f(i,s)\)表示到了第i轮,各种血量人数的情况为s今后的期望攻击boss次数.那么有\(f(i,s)=\frac{1}{num+1}*\sum_{s->s'}( ...
随机推荐
- HashSet中存放不重复元素
一.自定义对象存放在hashSet中,保证元素不重复.重写hashCode()和equals()方法 public class Student{ private String name; privat ...
- Oss文件存储
包含文件的上传下载和生成临时的url # -*- coding: utf-8 -*- import os import oss2 import configparser from Config imp ...
- Bridge (br0) Network on Linux
动手实践虚拟网络 - 每天5分钟玩转 OpenStack(10) - CloudMan - 博客园https://www.cnblogs.com/CloudMan6/p/5296573.html li ...
- 关于标准的知识 GB ISO 等内容
1. 来自百度知道: GB:GB 即"国标"的汉语拼音缩写,为中华人民共和国国家标准的意思. ISO:国际标准化组织的英语简称.其全称是International Organiza ...
- pojo类自动生成序列化ID
自动生成序列化ID
- synchronized与volatile的区别及各自的作用、原理(学习记录)
synchronized与volatile的区别,它们的作用及原理? 说到两者的区别,先要了解锁提供的两种特性:互斥(mutual exclusion) 和可见性(visibility). 互斥:即一 ...
- 每日一小时linux(1)--sysRq
参考https://www.ibm.com/developerworks/cn/linux/l-cn-sysrq/index.html SysRq 是什么 你是否遇到服务器不能通过 SSH 登录,也不 ...
- WEX5中ajax跨域访问的几种方式
1.使用jsonp方式 使用jsonp访问的话,前端需要把回调函数名传递给后端,后端执行完后也需要把回调函数传回给前端,默认情况下ajax自动生成一个回调函数名,后端可以通过String callba ...
- 图像识别opencv学习自修第一天【opencv的安装】
1. 安装步骤 (1)安装python (2)安装xcode (3)使用macports现成包安装opencv (4)安装scipy 2. 安装实战 (1)已经安装好了python,并安装好了virt ...
- ImportError: No module named google.protobuf.internal
下载: protobuf-3.3.0 设置路径:export PYTHONPATH=/gruntdata/lihaiyang/local/protobuf-3.3.0/python:$PYTHONPA ...