luogu P3758 [TJOI2017]可乐

背景:

上周为了那个勤写标兵 Lv3 \text{Lv3} Lv3没有写博客,现在补补坑。
现在也没有拿到,差评。

题目传送门:

https://www.luogu.org/problemnew/show/P3758

题意:

一个无向图,现在在每一个点有 3 3 3种选择,走到相邻的格子或静止或自爆(从此不再工作),问 t t t时刻后的方案数。

思路:

思路与[TJOI2019]甲苯先生的字符串类似。
走到相邻的格子相当于两个点的初始矩阵的格子对应的为 1 1 1
静止相当于对角线的格子为 1 1 1
自爆相当于连向一个不存在的点,并且从此静止(即单向连向 0 0 0,并且 0 0 0也连向 0 0 0)。
自乘 t t t遍即可。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 2017
using namespace std;
	int n,m,t;
	int bz[35][35];
struct node
{
	int a[35][35];
	void clear()
	{
		memset(a,0,sizeof(a));
	}
	friend node operator * (const node &a,const node &b)
	{
		node c;
		c.clear();
		for(int i=0;i<=n;i++)
			for(int j=0;j<=n;j++)
				for(int k=0;k<=n;k++)
					c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
		return c;
	}
} base;
int work(int x)
{
	node ans;
	ans.clear();
	for(int i=0;i<=n;i++)
		ans.a[i][i]=1;
	while(x)
	{
		if(x&1) ans=ans*base;
		base=base*base;
		x>>=1;
	}
	int sum=0;
	for(int i=0;i<=n;i++)
		sum=(sum+ans.a[1][i])%mod;
	return sum;
}
int main()
{
	int x,y;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&x,&y);
		bz[x][y]=bz[y][x]=1;
	}
	for(int i=0;i<=n;i++)
		bz[i][0]=bz[i][i]=1;
	memcpy(base.a,bz,sizeof(base.a));
	scanf("%d",&t);
	printf("%d",work(t));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值