P2579 [ZJOI2005]沼泽鳄鱼

传送门

显然可以列出 $dp$ 方程按时间转移

发现数据 $n$ 很小,$K$ 很大,考虑矩阵快速幂优化转移

但是不同时间的转移似乎不一样

发现题目中单个鱼的移动有周期性,显然整体的移动也有周期性,发现个体的周期只有 $2,3,4$

所以整体移动的周期最多也只有 $12$,所以考虑把 $12$ 步的转移一起考虑,最后剩下几步再暴力转

这样每 $12$ 步的转移都一样了

所以对于 $12$ 步一起的情况,直接把每一步的转移矩阵 $F[i],i \in [1,12]$ 乘在一起变成另一个转移矩阵 $G$ 做快速幂就好了

注意题目中点从 $0$ 标号,个人习惯从 $1$ 开始标号

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int 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;
}
const int N=57,mo=1e4;
int n,m,S,T,K;
inline int fk(int x) { return x>=mo ? x-mo : x; }
struct Matrix {
    int a[N][N];
    Matrix () { memset(a,0,sizeof(a)); }
    inline Matrix operator * (const Matrix &tmp) const {
        Matrix res;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++)
                    res.a[i][j]=fk(res.a[i][j]+a[i][k]*tmp.a[k][j]%mo);
        return res;
    }
}Ans,F[N],G;
Matrix ksm(Matrix X,int y)
{
    Matrix res;
    for(int i=1;i<=n;i++) res.a[i][i]=1;
    while(y)
    {
        if(y&1) res=res*X;
        X=X*X; y>>=1;
    }
    return res;
}
int main()
{
    n=read(),m=read(),S=read()+1,T=read()+1,K=read();
    int a,b,tot,p[7];
    for(int i=1;i<=m;i++)
    {
        a=read()+1,b=read()+1;
        F[0].a[a][b]=F[0].a[b][a]=1;
    }
    for(int i=1;i<=12;i++) F[i]=F[0];
    tot=read();
    for(int i=1;i<=tot;i++)
    {
        a=read();
        for(int j=0;j<a;j++) p[j]=read()+1;
        for(int j=1;j<=12;j++)
        {
            int t=p[j%a];
            for(int k=1;k<=n;k++) F[j].a[k][t]=0;
        }
    }
    G=F[1]; for(int i=2;i<=12;i++) G=G*F[i];
    int t=K/12,s=K%12; Ans.a[1][S]=1;
    Ans=Ans*ksm(G,t);
    for(int i=1;i<=s;i++) Ans=Ans*F[i];
    printf("%d\n",Ans.a[1][T]);
    return 0;
}

原文地址:https://www.cnblogs.com/LLTYYC/p/11279085.html

时间: 2024-11-04 02:52:43

P2579 [ZJOI2005]沼泽鳄鱼的相关文章

P2579 [ZJOI2005]沼泽鳄鱼(邻接矩阵,快速幂)

题目简洁明了(一点都不好伐) 照例,化简题目 给一张图,每一个时间点有一些点不能走,(有周期性),求从起点第k秒恰好在终点的方案数,可重复,不可停留. 额dp实锤 于是就被打脸了.... 有一种东西叫做邻接矩阵,还有一种东西叫做矩阵乘法,bk201大仙曾经讲过,能用邻接矩阵的k次方求这个东西. 那,难度下降了很多了. 但是,对于那周期是3,4,6的鳄鱼怎么办呢? 答案就是: 观察3,4,6,lcm(3,4,6)=12,所以,当k%12==0,鳄鱼们都回到了原状态. 所以,我们就暴力地对于每一种情

bzoj1898 [Zjoi2005]沼泽鳄鱼

Description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客.为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石桥.这个景点造好之后一直没敢对外开放,原因是池塘里有不少危险的食人鱼.豆豆先生酷爱冒险,他一听说这个消息,立马赶到了池塘,想做第一个在桥上旅游的人.虽说豆豆爱冒险,但也不敢拿自己的性命开玩笑,于是他开始了仔细的实地勘察,并得到了一些

[luogu2579 ZJOI2005] 沼泽鳄鱼(矩阵快速幂)

传送门 题目描述 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客. 为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石桥.这个景点造好之后一直没敢对外开放,原因是池塘里有不少危险的食人鱼. 豆豆先生酷爱冒险,他一听说这个消息,立马赶到了池塘,想做第一个在桥上旅游的人.虽说豆豆爱冒险,但也不敢拿自己的性命开玩笑,于是他开始了仔细的实地勘察,并得到了一些惊

【BZOJ1898】[Zjoi2005]Swamp 沼泽鳄鱼 矩阵乘法

[BZOJ1898][Zjoi2005]Swamp 沼泽鳄鱼 Description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客.为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石桥.这个景点造好之后一直没敢对外开放,原因是池塘里有不少危险的食人鱼.豆豆先生酷爱冒险,他一听说这个消息,立马赶到了池塘,想做第一个在桥上旅游的人.虽说豆豆爱冒险,但也不

BZOJ 1898: [Zjoi2005]Swamp 沼泽鳄鱼

1898: [Zjoi2005]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1085  Solved: 604[Submit][Status][Discuss] Description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客.为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石

BZOJ 1898: [Zjoi2005]Swamp 沼泽鳄鱼 [矩阵乘法]

1898: [Zjoi2005]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1082  Solved: 602[Submit][Status][Discuss] Description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客.为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石

1898: [Zjoi2005]Swamp 沼泽鳄鱼

矩阵乘法. 邻接矩阵用矩阵乘法可以得到最后的方案数 食人鱼是周期性的移动可以用12个矩阵表示.12个矩阵乘在一起得到第13个矩阵. 然后k/12的部分用第13个矩阵快速幂转移,再乘下剩余的矩阵. #include<cstdio> #include<algorithm> #include<cstring> #define LL long long using namespace std; const int maxn = 50 + 10; const int mod =

bzoj1898: [Zjoi2005]Swamp 沼泽鳄鱼

一眼矩乘 把图分成12个,然后直接搞. #include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL mod=10000; int n; struct Matrix { LL a[

矩阵乘法专题3——bzoj 1898 [Zjoi2004]Swamp 沼泽鳄鱼 题解

[原题] 1898: [Zjoi2004]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 425  Solved: 256 [Submit][Status] Description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客.为了让游玩更有情趣,人们在池塘的中央建设了几座石墩和石桥,每座石桥连接着两座石墩,且每两座石墩之间至多只有一座石桥.这