【luogu P4007 清华集训2017】小Y和恐怖奴隶主
题目背景
“A fight? Count me in!” 要打架了,算我一个。
“Everyone, get in here!” 所有人,都过来!
题目描述
小 Y 是一个喜欢玩游戏的 OIer。一天,她正在玩一款游戏,要打一个 Boss。
虽然这个 Boss 有 10100 点生命值,但它只带了一个随从—---一个只有 m 点生命值的 ‘‘恐怖的奴隶主’’。
这个 ‘‘恐怖的奴隶主’’ 有一个特殊的技能:每当它被扣减生命值但没有死亡(死亡即生命值 ≤ 0),且 Boss 的随从数量小于上限 k,便会召唤一个新的具有 m 点生命值的‘恐怖的奴隶主’’。
现在小 Y 可以进行 n 次攻击,每次攻击时,会从 Boss 以及 Boss 的所有随从中的等概率随机选择一个,并扣减 1 点生命值,她想知道进行 n 次攻击后扣减 Boss 的生命值点数的期望。为了避免精度误差,你的答案需要对 998244353 取模。
输入输出格式
输入格式:
从文件 patron.in 中读入数据。
输入第一行包含三个正整数 T; m; k, T 表示询问组数, m; k 的含义见题目描述。
接下来 T 行,每行包含一个正整数 n,表示询问进行 n 次攻击后扣减 Boss 的生命
值点数的期望。
输出格式:
输出到文件 patron.out 中。
输出共 T 行,对于每个询问输出一行一个非负整数,表示该询问的答案对 998244353取模的结果。
可以证明,所求期望一定是一个有理数,设其为 p/q(gcd(p; q) = 1),那么你输出的数 x 要满足 p ≡ qx (mod 998244353)。
题意:一个boss,初始带了一个小怪兽(满血为m 1->3),你打一下小怪兽(-1)如果它没死并且当前怪兽数不超过上限k(1-9),就会召唤另一个满血的小怪兽,或者你打一下boss对它造成1的伤害,它比较自信,不会再召唤什么奇怪的东东,求n轮(n<=1e18)对怪兽伤害的期望;
题解:
①让我们来观察一下诡异的数据范围:1e18 8 3 ,矩阵幂优化dp吧。。。。
②dp[h,i,j,k] 表示第h轮,血量为1 2 3 的怪兽个数为 i j k 的概率,再打一次伤害期望贡献为$\frac{dp[h,i,j,k]}{i+j+k+1}$,同时转移到其他状态的概率是$\frac{1}{i+j+k+1}$;省去h,把 dp[i,j,k] 重新定义成长度为1*tot的行矩阵,再定义一个tot*tot的矩阵,初始时tot*tot的矩阵可以dp推出,上快速幂
③统计答案,因为打怪兽和打boss是等概率的,比较方便的是再多加一位tot+1,A[tot+1][tot+1] = 1,这样就可以统计每一次的答案,最后输出ans[tot+1]即可;
④比较重要的是复杂度,根据插隔板的原理(详见白书P104) $tot = \sum_{i=2}^{10}C_{i}^{2} = 165$ $O(tot^{3}log n*T)$。 倍增预处理后面的(tot+1)*(tot+1)的矩阵的2^k把复杂度里的*T换成+T*lg n就好了;
⑤卡常(心累):其它奇技淫巧就不赘述了,主要是在矩阵乘法的时可以先用一个大数lim = k*mod(k∈Z),超了就减去lim,最后再取模(异常缓慢的取模运算)。
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll unsigned long long
using namespace std;
const int mod=;
const ll lim=16940360401038606353llu;
int T,m,p,ans[],tot,id[][][],inv[];
ll n;
struct Mat{
ll v[][];
Mat(){memset(v,,sizeof(v));}
ll *operator[](int a){return v[a];}
Mat operator *(const Mat &a){
Mat ret;
for(int i=;i<=tot+;i++)
for(int j=;j<=tot+;j++){
for(int k=;k<=tot+;k++){
ret.v[i][j]+=v[i][k]*a.v[k][j];
if(ret.v[i][j]>=lim) ret.v[i][j]-=lim;
}
ret.v[i][j]%=mod;
}
return ret;
}
}A[];///
char gc(){
static char *p1,*p2,s[];
if(p1==p2) p2=(p1=s)+fread(s,,,stdin);
return(p1==p2)?EOF:*p1++;
}//
ll rd(){
ll x=; char c=gc();
while(c<''||c>'') c=gc();
while(c>=''&&c<='') x=x*+c-'',c=gc();
return x;
}//
void pre(){
inv[]=;for(int i=;i<=p+;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=;i<=p;i++)
for(int j=;j<=(m>?p-i:);j++)
for(int k=;k<=(m>?p-i-j:);k++)
id[i][j][k] = ++tot;
for(int i=;i<=p;i++)
for(int j=;j<=(m>?p-i:);j++)
for(int k=;k<=(m>?p-i-j:);k++){
int np=id[i][j][k],nk=(i+j+k<p),ni=inv[i+j+k+];
if(m==) if(i) A[][np][id[i-][j][k]] = 1ll*i*ni%mod;
if(m==) {
if(i) A[][np][id[i-][j][k]] = 1ll*i*ni%mod;
if(j) A[][np][id[i+][j-+nk][k]] = 1ll*j*ni%mod;
}
if(m==) {
if(i) A[][np][id[i-][j][k]] = 1ll*i*ni%mod;
if(j) A[][np][id[i+][j-][k+nk]] = 1ll*j*ni%mod;
if(k) A[][np][id[i][j+][k-+nk]] = 1ll*k*ni%mod;
}
A[][np][np]=A[][np][tot+]=ni;
}
A[][tot+][tot+]=;
for(int i=;i<=;i++) A[i]=A[i-]*A[i-];
}///
void mul(int *ans,Mat M){
ll ret[];
for(int j=;j<=tot+;j++){
ret[j] = ;
for(int k=;k<=tot+;k++) {
ret[j] += ans[k] * M.v[k][j];
if(ret[j]>=lim) ret[j] -=lim;
}
ret[j] %= mod;
}
for(int j=;j<=tot+;j++) ans[j]=ret[j];
}///
int main()
{ freopen("mzoj1121.in","r",stdin);
freopen("mzoj1121.out","w",stdout);
T=rd(); m=rd(); p=rd();
pre();
while(T--){
n=rd();
memset(ans,,sizeof(ans));
if(m==) ans[id[][][]]=;
else if(m==) ans[id[][][]]=;
else ans[id[][][]]=;
for(int i=;i>=;i--) if(n>>i&) mul(ans,A[i]); //
printf("%d\n",ans[tot+]);
}
return ;
}//by tkys_Austin;
【luogu P4007 清华集训2017】小Y和恐怖奴隶主的更多相关文章
- [清华集训2017]小 Y 和地铁(神奇思路,搜索,剪枝,树状数组)
世界上最不缺的就是好题. 首先考虑暴搜.(还有什么题是从这东西推到正解的……) 首先单独一个换乘站明显没用,只用考虑一对对的换乘站. 那么有八种情况:(从题解偷图) 然后大力枚举每个换 ...
- 【luogu P4005 清华集训2017】小Y和地铁
题目描述 小 Y 是一个爱好旅行的 OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的一条曲线,不同线路的交点处一定会设有 换乘站 . ...
- 【清华集训】小Y和地铁
图已挂,前往luogu 题目: 小 $\rm Y$ 是一个爱好旅行的 $\rm OIer$.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁.她发现每条地铁线路可以看成平面上的一条 ...
- 清华集训2017D2T1 小 Y 和地铁(metro)
题目:https://www.luogu.org/problem/show?pid=P4005 题意:一条线段,给定n个点(n<=44)其中每个点可能对应另外一个点.如果一个点有对应点,那么就要 ...
- Loj #2324. 「清华集训 2017」小 Y 和二叉树
Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...
- 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)
[UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...
- loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主
#2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 "A fight? Co ...
- [LOJ#2324]「清华集训 2017」小Y和二叉树
[LOJ#2324]「清华集训 2017」小Y和二叉树 试题描述 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙 ...
- [LOJ#2323]「清华集训 2017」小Y和地铁
[LOJ#2323]「清华集训 2017」小Y和地铁 试题描述 小Y是一个爱好旅行的OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的 ...
随机推荐
- Python 图片转字符画
Python 图片转字符画 一.课程介绍 1. 课程来源 原创 2. 内容简介 本课程讲述怎样使用 Python 将图片转为字符画 3. 前置课程 Python编程语言 Linux 基础入门(新版) ...
- HP DL380服务器RAID信息丢失数据恢复方法和数据恢复过程分享
[数据恢复故障描述] 客户服务器属于HP品牌DL380系列,存储是由6块73GB SAS硬盘组成的RAID5,操作系统是WINDOWS 2003 SERVER,主要作为企业部门内部的文件服务器来 ...
- Python内置函数(8)——bool
英文文档: class bool([x]) Return a Boolean value, i.e. one of True or False. x is converted using the st ...
- Map集合、散列表、红黑树介绍
前言 声明,本文用得是jdk1.8 前面已经讲了Collection的总览和剖析List集合: Collection总览 List集合就这么简单[源码剖析] 原本我是打算继续将Collection下的 ...
- 搭建ssm框架,可实现登录和数据展示以及增删改查
需求: 后台使用ssm(spring-springMVC-mybatis)进行整合 前台使用bootstrap框架 前后台交互使用Ajax进行发送 表结构: 登录页面后显示所有用户信息,可对每条进行增 ...
- SQL Server 利用触发器对多表视图进行更新
其步骤就是:利用update操作触发器产生的2个虚拟表[inserted]用来存储修改的数据信息和[deleted]表,然后将对应的数据更新到对应数据表中的字段信息中: 1.首先创建3个表: a.信息 ...
- Sublime Text3 运行Python 出现Error:Decode error - output not utf-8
问题描述: Sublime Text 3 在build Python时,如果python源代码输出有中文,例如"print('中文')",Sublime Text 会报 [Deco ...
- Django(博客系统):基于pycharm如何一个django工程下创建多个app
背景:通常我们创建一个django系统时,为了把业务模块划分清楚往往会把一个独立的业务模块放到一个app中,如果多个独立的业务模块就会创建多个app,一般情况下为了更好的管理这些app,会把他们都存放 ...
- Django(博客系统):重写了auth.User后使用createsupperuser出错解决办法
背景:重写django的系统User后,使用createsupperuser创建用户失败 由于项目需要扩展django默认新的auth.User系统(添加两个字段:头像.简介等字段),因此就重写了dj ...
- Django之auth模块(用户认证)
auth模块简介 auth模块是对登录认证方法的一种封装,之前我们获取用户输入的用户名及密码后需要自己从user表里查询有没有用户名和密码符合的对象, 而有了auth模块之后就可以很轻松的去验证用户的 ...