题解:P8624 [蓝桥杯 2015 省 AB] 垒骰子

P8624 题解

题面

原题传送门

思路

首先看完题目很自然的想到可以设 dpi,j 表示第 i 个骰子以 j 面朝上的方案数。

首先对立关系由于总共才 6 种情况,所以可以直接用一个二维数组 mpi,j 来存,i,j 排斥为 0,否则为 1

初始化就是 dp1 的所有方案数为 1

考虑转移,dpi,j=6k=1dpi1,oppk×mpj,oppk

其中,oppi 表示 i 的对面。

opp[10]={0,4,5,6,1,2,3}

但是 n109,这么做显然是不行的,考虑矩阵加速。

对于样例,我们有如下式子。

[dpn,1dpn,2dpn,3dpn,4dpn,5dpn,6]=[111101111011111111111111111111111111]n1×[dpn1,1dpn1,2dpn1,3dpn1,4dpn1,5dpn1,6]

统计答案 ans 非常简单,就直接将最终得到的矩阵的值全部加起来即可。

当然这样子是不行的,因为每一个筛子因为侧边是可以旋转的,都有 4 种摆法,所以最终得到的 ans 还得乘上 4n,快速幂解决即可(记得取模。。。)。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int MN=40;
const int mod=1e9+7;
ll n,m,u,v,mp[MN][MN],ans,opp[MN]={0,4,5,6,1,2,3};
void write(ll n){if(n<0){putchar('-');write(-n);return;}if(n>9)write(n/10);putchar(n%10+'0');}
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
struct matrix{
    ll g[7][7];
    void clear(){memset(g,0,sizeof(g));}
}f1,f2;
inline matrix operator * (matrix a, matrix b){
	matrix c;c.clear();
	for(int i=1; i<=6; i++) for(int j=1; j<=6; j++) for(int k=1; k<=6; k++) c.g[i][j]=(c.g[i][j]+(a.g[i][k]*b.g[k][j])%mod)%mod;
	return c;
}
inline matrix operator ^ (matrix a, ll b){
	matrix ans;ans.clear();
    for(int i=1; i<=6; i++) ans.g[i][i]=1;
	while(b){
		if(b&1) ans=ans*a;
		a=a*a;
		b>>=1;
	}
	return ans;
}
ll ksm(ll a, ll b){
    ll res=1;
    while(b){
        if(b&1) res=(res*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return res;
}
void init(){
    for(int i=1; i<=6; i++) f2.g[i][1]=1;
    for(int i=1; i<=6; i++) for(int j=1; j<=6; j++) f1.g[i][j]=mp[i][opp[j]]^1;
}
int main(){
    // freopen("1.in","r",stdin);
    n=read();m=read();
    for(int i=1; i<=m; i++){
        u=read();v=read();
        mp[u][v]=mp[v][u]=1;
    }
    init();
    matrix res=(f1^(n-1))*f2;
    for(int i=1; i<=6; i++) ans=(ans+res.g[i][1])%mod;
    ans=(ans*ksm(4,n))%mod;
    write(ans);
	return 0;
}
posted @   naroto2022  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示
春潮带雨晚来急,野渡无人舟自横。