题目链接

首先dp很显然,\(f(i,s)\)表示到了第i轮,各种血量人数的情况为s今后的期望攻击boss次数。那么有\(f(i,s)=\frac{1}{num+1}*\sum_{s->s'}(f(i+1,s')+0/1)\),num为奴隶主个数,当攻击boss时后面的贡献就是1,否则是0,s可以用一个m位k+1进制数来表示(代表血量为1,2,3的奴隶主个数)。

然后处理出s的转移需要哪些状态(总状态数为\(tot=C_{10}^2+C_9^2+...+C_2^2=165\)),那么可以矩乘优化了。由于有多组询问,因此可以预处理出矩阵的\(2^k\)次方,但由于这样做询问时的复杂度还是\(O(tot^3logn)\)的,我们想到最边上的矩阵是\(tot*1\)的,且一个\(tot*tot\)的矩阵与\(tot*1\)的矩阵乘出来还是\(tot*1\)的,因此可以从\(tot*1\)的矩阵开始一路向左乘,这样复杂度就是\(O(tot^2logn)\)的。

总复杂度\(O(tot^3logn+T*tot^2logn)\),矩乘那里需要卡卡常。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#define P puts("lala")
#define cp cerr<<"lala"<<endl
#define ln putchar('\n')
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
inline int read()
{
char ch=getchar();int g=1,re=0;
while(ch<'0'||ch>'9') {if(ch=='-')g=-1;ch=getchar();}
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+(ch^48),ch=getchar();
return re*g;
}
typedef long long ll;
typedef pair<int,int> pii; const int N=201;
const int mod=998244353;
const ll MOD=(0x7fffffffffffffffll/mod-mod)*mod;
const ll MAXN=1e18;
const int maxb=59;
ll qpow(ll a,int n)
{
ll ans=1;
for(;n;n>>=1,a=a*a%mod) if(n&1) ans=ans*a%mod;
return ans;
}
struct mat
{
int n,m;
int s[169][169];
mat() {clean();}
void clean() {memset(s,0,sizeof(s));n=m=0;}
};
mat c;
ll tmp[169][169];
mat operator * (const mat &a,const mat &b)
{
c.n=a.n; c.m=b.m;
for(int i=0;i<a.n;++i) for(int k=0;k<a.m;++k)
{
if(!a.s[i][k]) continue;
for(int j=0;j<b.m;++j) if((tmp[i][j]+=1ll*a.s[i][k]*b.s[k][j])>=MOD)
tmp[i][j]-=MOD;
//c.s[i][j]=(c.s[i][j]+1ll*a.s[i][k]*b.s[k][j]%mod)%mod;
}
for(int i=0;i<c.n;++i) for(int j=0;j<c.m;++j)
c.s[i][j]=tmp[i][j]%mod,tmp[i][j]=0;
return c;
}
mat matpw[70],X,V;
int id[N],is[N],tot=0,pw[15],K,m,k;
ll n; void wj()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
#endif
}
int main()
{
wj();
int i,j,opt,T;
T=read(); m=read(); k=read();
K=k+1; pw[0]=1;
for(i=1;i<=m;++i) pw[i]=pw[i-1]*K;
for(i=0;i<pw[m];++i)
{
int s=0;
for(j=0;j<m;++j) s+=i/pw[j]%K;
if(s<=k) is[tot]=i,id[i]=tot,tot++;
}
X.n=tot+1; X.m=1;
X.s[tot][0]=1; matpw[0].n=matpw[0].m=tot+1;
matpw[0].s[tot][tot]=1;
for(int idx=0;idx<tot;++idx)
{
int num=0;
for(i=0;i<m;++i) num+=is[idx]/pw[i]%K;
int inv=qpow(num+1,mod-2);
matpw[0].s[idx][tot]=inv; matpw[0].s[idx][idx]=inv;
int x=is[idx];
for(i=0;i<m;++i) if(x/pw[i]%K)
{
x-=pw[i];
if(i) x+=pw[i-1];
if(i&&num<k) x+=pw[m-1];
(matpw[0].s[idx][id[x]]+=1ll*inv*(is[idx]/pw[i]%K)%mod)%=mod;
x=is[idx];
}
}
for(i=1;i<=maxb;++i) matpw[i]=matpw[i-1]*matpw[i-1];
int ans=pw[m-1];
for(int cas=1;cas<=T;++cas)
{
scanf("%lld",&n);
V=X;
for(i=0;i<=maxb;++i) if(n&(1ll<<i)) V=matpw[i]*V;
printf("%d\n",V.s[id[ans]][0]);
}
return 0;
}

LOJ2325「清华集训 2017」小Y和恐怖的奴隶主的更多相关文章

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

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

  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. MySQL主从复制原理及搭建过程

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 复制概述 复制即把一台服务器上的数据通过某种手段同步到另外一台或多台从服务器上,使得从服务器在数据上与主服务器保持一致. ...

  2. 完整代码:安卓小软件“CSV联系人导入导出工具”

    完整代码:安卓小软件"CSV联系人导入导出工具" 开发了一个安卓小软件"CSV联系人导入导出工具",欢迎测试.本软件可以帮你快速备份和恢复联系人,不用担心号码遗 ...

  3. 一文带你掌握Spring Web异常处理方式

    一.前言 大家好,我是 去哪里吃鱼 ,也叫小张. 最近从单位离职了,离开了五年多来朝朝夕夕皆灯火辉煌的某网,激情也好悲凉也罢,觥筹场上屡屡物是人非,调转过事业部以为能换种情绪,岂料和下了周五的班的前同 ...

  4. linux项目环境部署入门

    linux目录 /bin 二进制可执行命令 (ls,cat,mkdir等) /dev 设备特殊文件/etc 系统管理和配置文件/etc/rc.d 启动的配置文件和脚本 /opt 额外安装的可选应用程序 ...

  5. 我用Axure制作了一款火影小游戏 | PM老猫

    Axure不仅仅是一个原型工具,除了原型之外还可以用来制作一些静态网页,这点对于不懂代码或前端的同学来说挺实用.之前整理了一版<Axure函数自查表>,因为感觉内容太多又对前端样式及脚本感 ...

  6. 【美国血统 American Heritage 题解】已知前序中序 求后序

    题目: 题目名称:美国血统 American Heritage 题目来源:美国血统 American Heritage ## 题目描述 农夫约翰非常认真地对待他的奶牛们的血统.然而他不是一个真正优秀的 ...

  7. UOJ#XX A+B Problem (罔烙硫)

    题面 背景 题目描述 从前有个 n n n 个方格排成一行,从左至右依此编号为 1 , 2 , ⋯ , n 1,2,⋯,n 1,2,⋯,n. 有一天思考熊想给这 n n n 个方格染上黑白两色. 第 ...

  8. 字符串KMP——用途广泛的字符串匹配算法 + 扩展KMP——特殊定义的字符串匹配

    引 入 引入 引入 " SY 和 WYX 在看毛片.(几 毛 钱买到的动作 片,毛 片) WYX 突然想回味一个片段,但是只记得台词里面有一句挺长的 " ∗ ∗ ∗ ∗ **** ...

  9. 图床搭建|chrome插件|操作简单不要钱

    为什么需要一个图床 为了写博客 图床:专门用来存放图片,同时允许你把图片对外连接的网上空间. 用markdown格式写作,插入图片需要图片的url地址,然后博客的背景图也是要用url地址. 有段时间, ...

  10. [CISCN2019 华北赛区 Day1 Web2]ikun-1|python反序列化

    考点:JWT身份伪造.python pickle反序列化.逻辑漏洞 1.打开之后首页界面直接看到了提示信息,信息如下: 2.那就随便注册一个账号进行登录,然后购买lv6,但是未发现lv6,那就查看下一 ...