1217. 垒骰子 dp 矩阵乘法 快速幂
Published on 2022-11-17 23:01 in 暂未分类 with 林动

1217. 垒骰子 dp 矩阵乘法 快速幂

    赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。

    经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!

    我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。

    假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。

    atm想计算一下有多少种不同的可能的垒骰子方式。

    两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。

    由于方案数可能过多,请输出模 109+7 的结果。

    输入格式
    第一行包含两个整数 n,m,分别表示骰子的数目和排斥的组数。

    接下来 m 行,每行两个整数 a,b,表示 a 和 b 数字不能紧贴在一起。

    输出格式
    共一个数,表示答案模 109+7 的结果。

    数据范围
    1≤n≤109,
    1≤m≤36,
    1≤a,b≤6
    输入样例:
    2 1
    1 2
    输出样例:
    544

    import java.util.*;
    
    public class Main
    {
    	static int n,m,N=6,mod=1000000007;
    	static int a[][]=new int [N][N],f[][]=new int[N][N];
    	static int map(int x){
    		return (x+3)%6;
    	}
    	static void mul(int c[][],int a[][],int b[][]){
    		int t[][]=new int [N][N];
    		for(int i=0;i<N;++i){
    			for(int j=0;j<N;++j){
    				for(int k=0;k<N;++k){
    					t[i][j]=(int)((t[i][j]+(long)a[i][k]*b[k][j])%mod);
    				}
    			}
    		}
    		for(int i=0;i<N;++i){
    			for(int j=0;j<N;++j){
    				c[i][j]=t[i][j];
    			}
    		}
    	}
    	
    	public static void main(String args[])
    	{
    		Scanner sc=new Scanner(System.in);
    		n=sc.nextInt();
    		m=sc.nextInt();
    		for(int i=0;i<N;++i)Arrays.fill(a[i], 4);
    		for(int i=0;i<N;++i)f[0][i]=4;
    		while((m--)>0){
    			int x,y;
    			x=sc.nextInt();
    			y=sc.nextInt();
    			x--;y--;
    			a[map(y)][x]=0;
    			a[map(x)][y]=0;
    		}
    		
    		n--;
    		while(n>0){
    			if(n%2==1)mul(f,f,a);
    			mul(a,a,a);
    			n>>=1;
    		}
    		int ans=0;
    		for(int i=0;i<N;++i){
    			ans=(ans+f[0][i])%mod;
    		}
    		System.out.println(ans);
    	}
    }
    
    
    posted @   林动  阅读(9)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 地球OL攻略 —— 某应届生求职总结
    · 周边上新:园子的第一款马克杯温暖上架
    · Open-Sora 2.0 重磅开源!
    · 提示词工程——AI应用必不可少的技术
    · .NET周刊【3月第1期 2025-03-02】
    点击右上角即可分享
    微信分享提示