• 【题解】LOJ #2325 「清华集训 2017」小 Y 和恐怖的奴隶主(矩阵快速幂)


    【题解】LOJ #2325 「清华集训 2017」小 Y 和恐怖的奴隶主(矩阵快速幂)

    (f(i,a,b,c))表示进行到(i)次攻击,血量分别为(1,2,3)的怪的数量为(a,b,c)概率。如果你设表示攻击boss的次数期望的话就还要而外记录一个概率,不然无法转移,所以不如直接设成概率,每次转移(f(i,a,b,c) o f(i+1,a,b,c))的时候叠加一下答案即可(贡献为(f(i,a,b,c)over a+b+c+1)),可以看做是(ans(i)=ans(i-1)+sum {f(i,a,b,c)over a+b+c+1}),和(f)一起dp即可。

    状态数乍一看是(8^3),但是考虑到(a+b+cle 8),也就是方程(x_1+x_2+x_3+x_4=8)的解的个数,解的数量是({4+8-1choose 8}=165)

    那么考虑矩阵快速幂就好了,注意到询问次数比较多,用向量优化的方法就行了。

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;  typedef long long ll;
    inline ll qr(){
    	ll ret=0,f=0,c=getchar();
    	while(!isdigit(c)) f|=c==45,c=getchar();
    	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    const int mod=998244353;
    int MOD(const int&x){return x>=mod?x-mod:x;}
    int MOD(const int&x,const int&y){return 1ll*x*y%mod;}
    int st[10][10][10],vec[maxn],temp[maxn],id;
    //     1(a)2(b)3(c)
    
    const int maxn=166;
    struct{int x,y,z;}rem[maxn];
    struct MAT{
    	int v[maxn][maxn];
    	MAT(){memset(v,0,sizeof(int)*maxn*maxn);}
    	int* operator [](const int&x){return v[x];};
    	MAT operator * (const MAT&x)const{
    		MAT ret;
    		for(int k=0;k<=id;++k)
    			for(int t=0;t<=id;++t)
    				for(int i=0;i<=id;++i)
    					ret[t][i]=MOD(ret[t][i]+MOD(v[t][k],x.v[k][i]));
    		return ret;
    	}
    }mi[61];
    int ksm(const int&ba,const int&p){
    	int ret=1;
    	for(int t=p,b=ba;t;t>>=1,b=MOD(b,b))
    		if(t&1) ret=MOD(ret,b);
    	return ret;
    }
    
    int main(){
    	int T=qr(),m=qr(),k=qr();
    	for(int a=0;a<=k;++a)
    		for(int b=0;(b+a<=k&&m>=2)||b==0;++b)
    			for(int c=0;(a+b+c<=k&&m>=3)||c==0;++c)
    				rem[id]={a,b,c},st[a][b][c]=id++;
    	for(int t=0;t<id;++t){
    		int a=rem[t].x,b=rem[t].y,c=rem[t].z,inv=ksm(a+b+c+1,mod-2);
    		//hit boss
    		mi[0][t][t]=inv;
    		mi[0][t][id]=inv;
    		//hit a (1 hp)
    		if(a) mi[0][t][st[a-1][b][c]]=MOD(a,inv);		
    		//hit b (2 hp)
    		if(b) mi[0][t][st[a+1][b-1+(a+b<k&&m==2)][c+(a+b+c<k&&m==3)]]=MOD(b,inv);
    		//hit c (3 hp)
    		if(c) mi[0][t][st[a][b+1][c-1+(a+b+c<k)]]=MOD(c,inv);
    	}
    	mi[0][id][id]=1;
    	for(int t=1;t<=60;++t) mi[t]=mi[t-1]*mi[t-1];	
    	while(T--){
    		memset(vec,0,sizeof vec);
    		ll n=qr();
    		vec[st[m==1][m==2][m==3]]=1;
    		for(int t=0;t<=60;++t,n>>=1)
    			if(n&1){
    				memcpy(temp,vec,sizeof vec);
    				memset(vec,0,sizeof vec);
    				for(int j=0;j<=id;++j)
    					for(int i=0;i<=id;++i)
    						vec[i]=MOD(vec[i]+MOD(mi[t][j][i],temp[j]));
    			}
    		printf("%d
    ",vec[id]);
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:
    洛谷.3254.圆桌问题(最大流ISAP)
    BZOJ.2639.矩形计算(二维莫队)
    BZOJ.2724.[Violet 6]蒲公英(静态分块)
    BZOJ.4241.历史研究(回滚莫队 分块)
    BZOJ.4542.[HNOI2016]大数(莫队)
    SPOJ.COT2 Count on a tree II(树上莫队)
    BZOJ.3757.苹果树(树上莫队)
    洛谷.2325.[SCOI2005]王室联邦(贪心)
    BZOJ.1299.[LLH邀请赛]巧克力棒(博弈论 Nim)
    HDU.2516.取石子游戏(博弈论 Fibonacci Nim)
  • 原文地址:https://www.cnblogs.com/winlere/p/13023839.html
Copyright © 2020-2023  润新知