洛谷P2579 [ZJOI2005]沼泽鳄鱼(矩阵快速幂,周期)

例题:现在豆豆已经选好了两座石墩Start和End,他想从Start出发,经过K个单位时间后恰好站在石墩End上。假设石墩可以重复经过(包括Start和End),他想请你帮忙算算,这样的路线共有多少种(当然不能遭到食人鱼的攻击)。

输入格式:第一行包含五个正整数N,M,Start,End和K,分别表示石墩数目、石桥数目、Start石墩和End石墩的编号和一条路线所需的单位时间。石墩用0到N–1的整数编号。

第2到M + 1行,给出石桥的相关信息。每行两个整数x和y,0 ≤ x, y ≤ N–1,表示这座石桥连接着编号为x和y的两座石墩。

第M + 2行是一个整数NFish,表示食人鱼的数目。

第M + 3到M + 2 + NFish行,每行给出一条食人鱼的相关信息。每行的第一个整数是T,T = 2,3或4,表示食人鱼的运动周期。接下来有T个数,表示一个周期内食人鱼的行进路线。

如果T=2,接下来有2个数P0和P1,食人鱼从P0到P1,从P1到P0,……;

如果T=3,接下来有3个数P0,P1和P2,食人鱼从P0到P1,从P1到P2,从P2到P0,……;

 如果T=4,接下来有4个数P0,P1,P2和P3,食人鱼从P0到P1,从P1到P2,从P2到P3,从P3到P0,……。

豆豆出发的时候所有食人鱼都在自己路线上的P0位置,请放心,这个位置不会是Start石墩。

输出格式:输出路线的种数,因为这个数可能很大,你只要输出该数除以10000的余数就行了。

#include<cstdio>
#include<cstring>
const int mod = 10000;

int x,y,n,m,k,s,t,fish;
int res[30][5],tt[30];

struct Node{
    int a[60][60];
    Node operator *(const Node &x)const{
        Node ans;
        memset(ans.a,0,sizeof(a));
        for(int i = 0; i < n; ++i)
            for(int t = 0; t < n; ++t)
                for(int k = 0; k < n; ++k)
                    ans.a[i][t] = (ans.a[i][t]+a[i][k]*x.a[k][t]) % mod;
        return ans;
    }
}h[15],bb,base,ans;

void quick_pow(int k){
    while(k){
        if(k&1)  ans = ans*base;
        base = base*base;  k >>= 1;
    }
}

int main(){
    scanf("%d%d%d%d%d",&n,&m,&s,&t,&k);
    for(int i = 1; i <= m; ++i){
        scanf("%d%d",&x,&y);
        bb.a[x][y] = bb.a[y][x] = 1;
    } 
    scanf("%d",&fish);
    for(int i = 0; i < fish; ++i){
        scanf("%d",&tt[i]);
        for(int t = 0; t < tt[i]; ++t)  scanf("%d",&res[i][t]);
    }
    for(int i = 0; i < 12; ++i){
        h[i] = bb;
        for(int t = 0; t < fish; ++t)
            for(int k = 0; k < n; ++k)  h[i].a[k][res[t][(i+1)%tt[t]]] = 0;   
    }
    base = h[0];
    for(int i = 1; i < 12; ++i)  base = base*h[i];
    for(int i = 0; i < n; ++i)  ans.a[i][i] = 1;
    quick_pow(k/12);    
    for(int i = 1; i <= k%12; ++i)    ans = ans*h[i-1];
    printf("%d",ans.a[s][t]);
    return 0;
}

 

posted @ 2020-11-23 14:24  のNice  阅读(68)  评论(0编辑  收藏  举报