bzoj1898: [Zjoi2005]Swamp 沼泽鳄鱼

传送门 首先我们发现lcm(2,3,4)=12很小 于是我们预处理出12个时刻内所有合法转移 然后我们大力矩阵乘法就可以了。#include#include #include #include #include #include#define ll long lo
摘要由CSDN通过智能技术生成

传送门
首先我们发现lcm(2,3,4)=12很小
于是我们预处理出12个时刻内所有合法转移
然后我们大力矩阵乘法就可以了。

#include<cstring>
#include<cmath>   
#include<cstdio>  
#include<iostream>  
#include<cstdlib>   
#include<algorithm>
#define ll long long
#define N 50005
using namespace std;
struct edge{int x,y,z;}e[3005];
int n,m,s,t,k,p,fish[25][10];
struct matrix{
    int a[55][55];
    void clear(){memset(a,0,sizeof(a));}
    matrix operator * (const matrix b) const
    {
        matrix 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]=(a[i][k]*b.a[k][j]+c.a[i][j])%10000;
        return c;
    }
    void build(int tim){
        clear();
        int ok[55];
        memset(ok,1,sizeof(ok)); 
        for (int i=1;i<=p;i++) ok[fish[i][tim%fish[i][4]]]=0;
        for (int i=1;i<=m;i++){
            if (ok[e[i].x]) a[e[i].y][e[i].x]=1; 
            if (ok[e[i].y]) a[e[i].x][e[i].y]=1;
        }
    }
    matrix pow(int x){
        matrix c,d;
        c.clear();
        memcpy(d.a,a,sizeof(a));
        for (int i=0;i<n;i++) c.a[i][i]=1;
        while (x){
            if (x%2) c=c*d;
            d=d*d;
            x/=2;
        }
        return c;
    }
}ans,ppp[15]; 
int main(){
    scanf("%d%d%d%d%d",&n,&m,&s,&t,&k);
    for (int i=1;i<=m;i++) scanf("%d%d",&e[i].x,&e[i].y);
    scanf("%d",&p);
    for (int i=1;i<=p;i++){
        scanf("%d",&fish[i][4]);
        for (int j=0;j<fish[i][4];j++) scanf("%d",&fish[i][j]);
    }
    for (int i=1;i<=12;i++) ppp[i].build(i);
    for (int i=0;i<n;i++) ppp[0].a[i][i]=1;
    for (int i=1;i<=12;i++) ppp[i]=ppp[i-1]*ppp[i];
    ans=ppp[12].pow(k/12)*ppp[k%12];
    printf("%d",ans.a[s][t]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值