JZOJ 2288. [ZJOI2005] swamp crocodile [matrix multiplication]

Posted by n8r0x on Sat, 02 Nov 2019 00:19:18 +0100

233

Title:

Portal

Title:

There are nnn columns and mmm bridges connecting these columns.
There are also piranhas that limit our movement. Piranhas move periodically, but when they are in a certain pillar, we cannot go forward.
Now give the starting point and the ending point, and ask how many legal solutions are there

Analysis:

We need a pre knowledge: for a graph, g[i][j]ng[i][j]^ng[i][j]n represents the scheme of starting from iii and taking nnn steps to jjj.
So it's a little obvious.
The only thing we need to pay attention to is the period of fish. We can see that their periods are all 2, 3, 42, 3, 42, 3, 4, that is, step 121212 must be a large period.
We can treat every 121212 steps as a whole, and then solve it with fast power.
For those remaining steps, we can solve them by matrix multiplication and sequential multiplication alone

Code:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long 
#define LZX 10000
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
int n=read(),m=read(),b=read()+1,e=read()+1,t=read();
struct QWQ{
	int f[55][55];
}ans,iv,g[15],p;
int nd[5];
QWQ operator * (QWQ a,QWQ b)
{
	QWQ tem;
	memset(tem.f,0,sizeof(tem.f));
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=n;j++)
	    for(int k=1;k<=n;k++)
	      tem.f[i][j]=(tem.f[i][j]+a.f[i][k]*b.f[k][j])%LZX;
	return tem;
}
QWQ ksm(QWQ x,int y)
{
	QWQ tem=iv;
	while(y)
	{
		if(y&1) tem=tem*x;
		x=x*x;y>>=1;
	}
	return tem;
}
int main()
{
	for(int i=1;i<=m;i++) 
	{
		int x=read()+1,y=read()+1;
		for(int j=1;j<=12;j++)
		  g[j].f[x][y]=g[j].f[y][x]=1;
	}
	int fish=read();
	while(fish--)
	{
		int z=read();
		for(int i=1;i<=z;i++) nd[i]=read()+1;
		for(int i=1;i<=n;i++)
		  for(int j=0;j<=12;j++)
		    g[j].f[i][nd[j%z+1]]=0;
	}
	for(int i=1;i<=n;i++) iv.f[i][i]=p.f[i][i]=1;
	for(int i=1;i<=12;i++) p=p*g[i];
	ans=ksm(p,t/12);
	for(int i=1;i<=t%12;i++) ans=ans*g[i];
	cout<<ans.f[b][e];
	return 0;
}