题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1898

求到达方案数...还是矩阵快速幂;

能够到达就把邻接矩阵那里赋成1,有鳄鱼的地方从各处来的路径都是0;

因为时间周期只有2,3,4,所以每12个时间就是一个循环;

可以用矩阵快速幂做了。

一开始写了个一团糟,也不明白样例为什么输出0了...

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int const mod=;
int n,m,st,ed,K,head[],ct,nf,ey[][],te[],ans[],tmp[];
struct E{
int to,next;
E(int t=,int n=):to(t),next(n) {}
}edge[];
struct Matrix{
int a[][];
Matrix operator * (const Matrix &y) const
{
Matrix x;
memset(x.a,,sizeof x.a);
for(int i=;i<=n;i++)
for(int k=;k<=n;k++)
for(int j=;j<=n;j++)
(x.a[i][j]+=a[i][k]*y.a[k][j])%=mod;
return x;
}
}s[],b;
void add(int x,int y){edge[++ct]=E(y,head[x]); head[x]=ct;}
void build1()
{
for(int x=;x<=n;x++)
for(int i=;i<=;i++)
for(int j=head[x],u;j;j=edge[j].next)
s[i].a[x][u=edge[j].to]=;//
}
void build2()
{
for(int i=;i<=nf;i++)
for(int t=;t<=;t++)
for(int j=;j<=n;j++)
{
int x=ey[i][t%te[i]];
// for(int k=head[x],y;k;k=edge[k].next)
// s[j].a[y=edge[k].to][x]=0;
s[t].a[j][x]=;
}
}
//void init(Matrix &x)
//{
// memset(x.a,0,sizeof x.a);
// for(int i=1;i<=55;i++)
// for(int j=55;j;j--)
// x.a[i][j]=1;
//}
void mul2(int a[],int b[][],int c[])
{
int tmp[];
for(int j=;j<n;j++)
{
tmp[j]=;
for(int k=;k<n;k++)
tmp[j]=(tmp[j]+a[k]*b[k][j])%mod;
}
for(int j=;j<n;j++)
c[j]=tmp[j];
}
int main()
{
scanf("%d%d%d%d%d",&n,&m,&st,&ed,&K);
st++; ed++;
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
x++; y++;
add(x,y); add(y,x);
}
scanf("%d",&nf);
for(int i=;i<=nf;i++)
{
scanf("%d",&te[i]);
for(int j=;j<=te[i];j++)
scanf("%d",&ey[i][j]),ey[i][j]++;
}
build1(); build2();
// init(s[13]);
for(int i=;i<=n;i++)
b.a[i][i]=s[].a[i][i]=;
for(int i=;i<=;i++)s[]=s[]*s[i];
// Matrix b; init(b);
int t=K/;
while(t)
{
if(t&)b=b*s[];
s[]=s[]*s[];
t>>=;
}
t=K%;
for(int i=;i<=t;i++)b=b*s[i];
// for(int i=1;i<=55;i++)
// for(int j=1;j<=55;j++)
// if(b.a[i][j])printf("b:%d\n",b.a[i][j]);
// tmp[st]=1;
// for(int i=1;i<=n;i++)
// for(int j=1;j<=n;j++)
// (ans[i]+=tmp[j]*b.a[j][i])%=mod;
ans[st]=;
mul2(ans,b.a,ans);
printf("%d",ans[ed]);
return ;
}

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int const mod=;
int n,m,st,ed,K,nf,ey[];
struct Matrix{
int a[][];
Matrix operator * (const Matrix &y) const
{
Matrix x;
memset(x.a,,sizeof x.a);
for(int i=;i<=n;i++)
for(int k=;k<=n;k++)
for(int j=;j<=n;j++)
(x.a[i][j]+=a[i][k]*y.a[k][j])%=mod;
return x;
}
Matrix(){memset(a,,sizeof a);}//
void init()
{
for(int i=;i<=n;i++) a[i][i]=;
}
}s[],b;
Matrix operator ^ (Matrix a,int k)
{
Matrix ret; ret.init();
while(k)
{
if(k&)ret=ret*a;
a=a*a;
k>>=;
}
return ret;
}
int main()
{
scanf("%d%d%d%d%d",&n,&m,&st,&ed,&K);
st++; ed++;
for(int i=,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
x++; y++;
for(int j=;j<=;j++)
s[j].a[x][y]=s[j].a[y][x]=;
}
scanf("%d",&nf);
for(int i=,tt;i<=nf;i++)
{
scanf("%d",&tt);
for(int j=;j<=tt;j++)
scanf("%d",&ey[j]),ey[j]++;
for(int j=;j<=;j++)
for(int k=;k<=n;k++)
s[j].a[k][ey[j%tt+]]=;//+1
}
s[].init();
for(int i=;i<=;i++)s[]=s[]*s[i];
b=s[]^(K/);
for(int i=;i<=K%;i++)b=b*s[i];
printf("%d",b.a[st][ed]);
return ;
}

bzoj1898 [Zjoi2005]Swamp 沼泽鳄鱼——矩阵快速幂的更多相关文章

  1. BZOJ1898: [Zjoi2005]Swamp 沼泽鳄鱼(矩阵快速幂)

    题意 题目链接 Sol 不难发现吃人鱼的运动每\(12s\)一个周期 所以暴力建12个矩阵,放在一起快速幂即可 最后余下的部分暴力乘 #include<bits/stdc++.h> usi ...

  2. bzoj 1898 [Zjoi2005]Swamp 沼泽鳄鱼——矩阵快速幂

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1898 当然是邻接矩阵做转移矩阵来快速幂. 对于鳄鱼,好在它们周期的lcm是12,也就是每12 ...

  3. BZOJ1898 [Zjoi2005]Swamp 沼泽鳄鱼 矩阵

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1898 题意概括 有一个无向图. 其中,有许多条鱼在以循环的规律出现,比如循环在1,2,3这些点出现 ...

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

    [BZOJ1898][Zjoi2005]Swamp 沼泽鳄鱼 Description 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎 ...

  5. BZOJ1898: [Zjoi2005]Swamp 沼泽鳄鱼(矩阵乘法)

    1898: [Zjoi2005]Swamp 沼泽鳄鱼 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1898 Description 潘塔 ...

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

    1898: [Zjoi2005]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1082  Solved: 602[Submit][S ...

  7. 【BZOJ-1898】Swamp 沼泽鳄鱼 矩阵乘法

    1898: [Zjoi2005]Swamp 沼泽鳄鱼 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1012  Solved: 566[Submit][S ...

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

    传送门 题目描述 潘塔纳尔沼泽地号称世界上最大的一块湿地,它地位于巴西中部马托格罗索州的南部地区.每当雨季来临,这里碧波荡漾.生机盎然,引来不少游客. 为了让游玩更有情趣,人们在池塘的中央建设了几座石 ...

  9. BZOJ 1898 沼泽鳄鱼(矩阵快速幂)

    没有食人鱼不是裸题吗,用一个向量表示从s到1..N的距离,然后不停乘邻接矩阵行了,当然快速幂 有食人鱼,发现食人鱼最多十二个邻接矩阵一循环,处理出12个作为1个然后快速幂行了   怎么处理呢? 假设食 ...

随机推荐

  1. linux目录文件操作

    一.linux系统目录结构 1.顶层根目录 顶层根目录使用 “/”来表示 2.linux中的一些重要目录 (1)bin目录 放置常用的可执行文件(其中ls命令位列其中) (2)sbin目录 放置系统的 ...

  2. fielddata breaker与cache size

    breaker的估算,是根据语句以及上层的结果数,加上固定的值,不准确. cache.size是cache到结果的size,准确. 所以,配置breaker不能拦截占用内存的聚合查询,而配置cache ...

  3. vue 子组件修改父组件变量问题

    昨天遇到一个这样的场景, 主页面引用了一个子页面,子页面有个Redio选择,2个选项. 默认的,会从父组件传递一个参数给子组件作为默认值,实现默认选中效果,以及用来做反选. 开始没什么问题,页面都摆上 ...

  4. 编程数学(A-2)-次方

    百度百科:次方. 特别是一个数的负次方需要注意.

  5. POJ-1679 The Unique MST,次小生成树模板题

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K       Description Given a connected undirec ...

  6. hihoCoder#1120 小Hi小Ho的惊天大作战:扫雷·三

    原题地址 看上去非常复杂, 实际上是这一系列最简单的一步,本质上是个搜索过程,相比于前一道题,可以不用策略三,而且题目的数据规模超级小,所以暴力搜索就能过. 把尚未确定的点放在一个unsettled列 ...

  7. [luoguP1082] 同余方程(扩展欧几里得)

    传送门 ax≡1(mod b) 这个式子就是 a * x % b == 1 % b 相当于 a * x - b * y == 1 只有当 gcd(a,b) == 1 时才有解,也就是说 ax + by ...

  8. MTK平台添加防止误触代码

    ltr559_old: #include <linux/interrupt.h> #include <linux/i2c.h> #include <linux/slab. ...

  9. 【IntelliJ 】IntelliJ IDEA 自动导入包 快捷方式 关闭重复代码提示

    idea可以自动优化导入包,但是有多个同名的类调用不同的包,必须自己手动Alt+Enter设置 设置idea导入包 勾选标注 1 选项,IntelliJ IDEA 将在我们书写代码的时候自动帮我们优化 ...

  10. Operating system management of address-translation-related data structures and hardware lookasides

    An approach is provided in a hypervised computer system where a page table request is at an operatin ...