zoukankan      html  css  js  c++  java
  • 清华集训2017 小 Y 和*的奴隶主

    (dp_{i,a,b,c}​)表示前(i)次攻击,场上有(a)个一血 (b)个二血 (c) 个三血的概率
    还要再记一个(g_i)表示前(i)次对boss期望伤害
    算上(g)总共166个状态 可以矩阵快速幂了
    预处理矩阵的(2^k) 询问的时候只需要用一个行向量乘log个矩阵
    时间复杂度变为(O(T166^2logn))

    #include<bits/stdc++.h>
    using namespace std;
    #define fp(i,l,r) for(register int (i)=(l);(i)<=(r);++(i))
    #define fd(i,l,r) for(register int (i)=(l);(i)>=(r);--(i))
    #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next)
    #define mem(a) memset((a),0,sizeof (a))
    #define O(x) cerr<<#x<<':'<<x<<endl
    #define int long long
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    void wr(int x){
        if(x<0)x=-x,putchar('-');
        if(x>=10)wr(x/10);
        putchar('0'+x%10);
    }
    const int mod=998244353;
    inline void tmod(int &x){x%=mod;}
    inline int qpow(int a,int b){
    	int res=1;a%=mod;
    	for(;b;b>>=1,tmod(a*=a))
    		if(b&1)tmod(res*=a);
    	return res;
    }
    int id[9][9][9],cnt,T,m,K;
    struct Mat{
    	int a[170][170];
    	Mat(){mem(a);}
    	inline int *operator[](int x){return a[x];}
    	inline friend Mat operator*(Mat a,Mat b){
    		Mat c;
    		fp(i,1,cnt)fp(j,1,cnt){
    			__int128 t=0;
    			fp(k,1,cnt)t+=a[i][k]*b[k][j];
    			c[i][j]=t%mod;
    		}
    		return c;
    	}
    }s[60];
    int ans[170],tmp[170];
    inline void Mul(Mat c){
    	mem(tmp);
    	fp(i,1,cnt){
    		__int128 t=0;
    		fp(j,1,cnt)t+=c[j][i]*ans[j];
    		tmp[i]=t%mod;
    	}
    	fp(i,1,cnt)ans[i]=tmp[i];
    }
    main(){
    	T=read();m=read();K=read();
    	fp(i,0,K)
    		fp(j,0,m>=2?K-i:0)
    		fp(k,0,m>=3?K-i-j:0)
    		id[i][j][k]=++cnt;
    	++cnt;s[0][cnt][cnt]=1;
    	fp(a,0,K)fp(b,0,m>=2?K-a:0)fp(c,0,m>=3?K-a-b:0){
    		int t=id[a][b][c],iv=qpow(a+b+c+1,mod-2),ext=a+b+c<K;
    		if(a)s[0][t][id[a-1][b][c]]=a*iv%mod;
    		if(m==2&&b)s[0][t][id[a+1][b-1+ext][c]]=b*iv%mod;
    		if(m==3&&b)s[0][t][id[a+1][b-1][c+ext]]=b*iv%mod;
    		if(m==3&&c)s[0][t][id[a][b+1][c-1+ext]]=c*iv%mod;
    		s[0][t][cnt]=s[0][t][t]=iv;
    	}
    	fp(i,1,59)s[i]=s[i-1]*s[i-1];
    	while(T--){
    		int x=read();
    		mem(ans);ans[id[m==1][m==2][m==3]]=1;
    		fp(i,0,59)if(x>>i&1)Mul(s[i]);
    		printf("%lld
    ",ans[cnt]);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    「Vue」nrm
    「Vue」路由
    「Vue」父子组件之间的传值及调用方法
    「Vue」vue生命周期
    「Vue」自定义指令
    「Vue」自定义按键修饰符
    「Vue」过滤器
    常用断点设置
    BUUCTF 不一样的flag writeup
    好久没有写东西,最近在看逆向相关的东西,做点记录
  • 原文地址:https://www.cnblogs.com/misaka10047/p/13186500.html
Copyright © 2011-2022 走看看