传送门

uoj上的数据太毒了……也可能是我人傻常数大的缘故……

三种血量的奴隶主加起来不超过\(8\)个,可以枚举每种血量的奴隶主个数,那么总的状态数只有\(165\)种,设\(dp_{t,i,j,k}\)表示\(t\)时刻的时候\(i\)个一血奴隶主,\(j\)个二血奴隶主,\(k\)个三血奴隶主的概率,那么转移很明显

if(A)dp[i][A][B][C]+=dp[i-1][A-1][B][C]*A/tot;
if(B)dp[i][A][B][C]+=dp[i-1][A+1][B-1][C+ADD]*B/tot;
if(C)dp[i][A][B][C]+=dp[i-1][A][B+1][C-1+ADD]*C/tot;

\(tot\)是\(A+B+C+1\),\(ADD\)代表当前奴隶主总数是否小于\(k\)

然后期望伤害的话再记一个\(E\)数组就可以了

上面那个其实就是本题弱化版的题解,本题的话还需要一个矩阵加速

顺带一提,记得卡常

//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
ll read(){
R ll res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=185,M=15,P=998244353;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
int len,k,m;ll n,y;map<ll,int>mp;
int inv[N],id[M][M][M],ans[N],res[N];
struct Matrix{
int a[N][N];
Matrix(){memset(a,0,sizeof(a));}
inline int* operator [](const int &x){return a[x];}
friend Matrix operator *(Matrix a,Matrix b){
Matrix res;
fp(i,1,len+1)fp(k,1,len+1)if(a[i][k])fp(j,1,len+1){
res[i][j]=add(res[i][j],1ll*a[i][k]*b[k][j]%P);
}
return res;
}
}dp[N];
#define rep fp(A,0,k)fp(B,0,(m>1?k-A:0))fp(C,0,(m>2?k-A-B:0))
void init(){
inv[0]=inv[1]=1;
fp(i,2,10)inv[i]=1ll*inv[P%i]*(P-P/i)%P;
rep id[A][B][C]=++len;
rep{
int i=id[A][B][C],Inv=inv[A+B+C+1],add=(A+B+C<k);
if(m==1){
if(A)dp[0][i][id[A-1][B][C]]=1ll*A*Inv%P;
}else if(m==2){
if(A)dp[0][i][id[A-1][B][C]]=1ll*A*Inv%P;
if(B)dp[0][i][id[A+1][B-1+add][C]]=1ll*B*Inv%P;
}else{
if(A)dp[0][i][id[A-1][B][C]]=1ll*A*Inv%P;
if(B)dp[0][i][id[A+1][B-1][C+add]]=1ll*B*Inv%P;
if(C)dp[0][i][id[A][B+1][C-1+add]]=1ll*C*Inv%P;
}
dp[0][i][i]=dp[0][i][len+1]=Inv;
}
dp[0][len+1][len+1]=1;
fp(i,1,60)dp[i]=dp[i-1]*dp[i-1];
}
void Mul(R int *A,R Matrix &B){
fp(i,1,len+1)res[i]=0;
fp(i,1,len+1)if(A[i])fp(j,1,len+1)res[j]=add(res[j],1ll*A[i]*B[i][j]%P);
fp(i,1,len+1)A[i]=res[i];
}
int main(){
// freopen("testdata.in","r",stdin);
int T=read();m=read(),k=read();
init();
while(T--){
n=read();
if(mp.count(n)){print(mp[n]);continue;}
fp(i,1,len+1)ans[i]=0;
ans[id[m==1][m==2][m==3]]=1;
y=n;
for(R int i=0;y;++i,y>>=1)if(y&1)Mul(ans,dp[i]);
mp[n]=ans[len+1];
print(ans[len+1]);
}
return Ot(),0;
}

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

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

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

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

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

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

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

  4. 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个 ...

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

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

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

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

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

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

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

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

  9. 【清华集训】小Y和地铁

    图已挂,前往luogu 题目: 小 $\rm Y$ 是一个爱好旅行的 $\rm OIer$.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁.她发现每条地铁线路可以看成平面上的一条 ...

随机推荐

  1. 《高性能Javascript》 Summary(二)

    第四章.算法和流程控制 Algorithms And Flow Control 原因:代码整体结构是执行速度的决定因素之一.代码量少不一定运行速度快,代码量多不一定运行速度慢.性能损失与组织代码和具体 ...

  2. webpack-dev-server原理及要点笔记

    webpack-dev-server启动了一个使用express的Http服务器,这个服务器与客户端采用websocket通信协议,当原始文件发生改变,webpack-dev-server会实时编译. ...

  3. SQLSERVER2008 R2的端口设置

    通过存储过程查看 我们首先打开sqlserver连接sqlserver2008的数据库实例,然后执行如下存储过程: --查询端口号 exec sys.sp_readerrorlog 0, 1, 'li ...

  4. Buffer的数据存取

    缓冲区 存放要读取的数据 缓冲区 和 通道 配合使用 一个用于特定基本数据类行的容器.有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类. Java NIO中的Buffer主要用于与N ...

  5. 带动画效果的jQuery手风琴

    带动画效果的jQuery特效手风琴是一款带动画效果的手风琴作品,非常实用,可以用在新闻列表.FAQ等模块,默认的是打开第一个选项,查看其它的时候直接点击加号按钮就展开. 源码地址:http://www ...

  6. RQNOJ 169 最小乘车费用:水dp

    题目链接:https://www.rqnoj.cn/problem/169 题意: 给出行驶1-10公里的费用(所有车一样),可以倒车,问行驶n公里的最小费用. 题解: 大水题... (=´ω`=) ...

  7. &&、||和&、|的区别

    1. && .|| 和 &.| 都是逻辑运算符,前两个 与后两个的区别就在于 &&.|| 有"短路"现象,而& .| 则没有. 例如 ...

  8. dynamic 作为参数传入另一个程序集,获取值

    dynamicOBJ.GetType().GetProperty("key").GetValue(dynamicOBJ, null)

  9. Codeforces round 396(Div. 2) 题解

    Problem A 题目大意 给定两个字符串,要求构造出一个最长的一个串满足:这个串是其中一个串的字序列并且不是另一个串的子序列.输出长度.\((len \leq 10^5)\) 题解 千万年死在读题 ...

  10. tomcat集群--单tomcat多实例

    1.解压apache-tomcat-7.0.75.tar.gz到任意目录 /data/tomcat-4X 2.建立tomcat多实例目录,这个tomcat-4X运行4X应用的两个实例4002,4004 ...