bzoj1875 HH去散步

题目链接

一开始特别天真,

$Folyd$传递闭包写了一下过了样例就交上去了

然后$gg$

$qwq$

想了想$……$

还要写一点东西

最后统计答案的时候有细节要注意

/**************************************************************
    Problem: 1875
    User: zhangheran
    Language: C++
    Result: Accepted
    Time:17164 ms
    Memory:3876 kb
****************************************************************/
 
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
//#include"suqingnian.h"
#include<algorithm>
#include<cstring>
using namespace std;
const int mod=45989;
int n,m,t,a,b;
struct data{
    int v;int u;int next;
}edge[410];int alist[410];int cnt;
void add(int u,int v)
{
    edge[++cnt].u=u;
    edge[cnt].v=v;
    edge[cnt].next=alist[u];
    alist[u]=cnt;
    return ;
}
struct Martix{
    long long num[220][220];
    void hint(){memset(num,0,sizeof(num));for(int i=0;i<=m*2;i++) num[i][i]=1;}
    void clear(){memset(num,0,sizeof(num));}
    friend Martix operator *(const Martix &a,const Martix &b)
    {
        Martix c;
        memset(c.num,0,sizeof(c.num));
        for(int k=0;k<=m*2;k++)
          for(int i=0;i<=m*2;i++)
            for(int j=0;j<=m*2;j++)
              c.num[i][j]=(c.num[i][j]+a.num[i][k]*b.num[k][j]%mod)%mod;
        return c;
    }
    friend Martix operator +(const Martix &a,const Martix &b)
    {
        Martix c;memset(c.num,0,sizeof(c.num));
        for(int i=0;i<=m*2;i++)
          for(int j=0;j<=m*2;j++)
            c.num[i][j]=(a.num[i][j]+b.num[i][j])%mod;
        return c;
    }
};
Martix
    _pow(Martix _a,int _b)
    {
        Martix _res;_res.hint();
        for(;_b;_b >>= 1, _a= _a * _a )
          if(_b & 1) _res = _res * _a ;
        return _res ;
    }
int u,v;
Martix map,dis;
int ans=0;
int main()
{
    memset(alist,-1,sizeof(alist));
    scanf("%d%d%d%d%d",&n,&m,&t,&a,&b);
    a++,b++;
    for(int i=1;i<=m;i++) scanf("%d%d",&u,&v),add(u+1,v+1),add(v+1,u+1);
    int next=alist[a];
    while(next!=-1) map.num[0][next]++,next=edge[next].next;
    for(int i=1;i<=cnt;i++){
        v=edge[i].v,next=alist[v];
        while(next!=-1){
            if(next!=(i+((i&1)?1:-1)))
              dis.num[i][next]++;
            next=edge[next].next;
        }
    }
    dis=_pow(dis,t-1);
    map=map*dis;
//  for(int i=0;i<=m*2;i++,puts(""))
//    for(int j=0;j<=m*2;j++)
//      printf("%d ",map.num[i][j]);
    for(int i=1;i<=cnt;i++) if(edge[i].v==b) ans=(ans+map.num[0][i])%mod;
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-07-26 22:40  米罗偕涯  阅读(294)  评论(0编辑  收藏  举报