bzoj 1875: [SDOI2009]HH去散步

颓废题2

一看就是从一个点可以推到下一个点,明显的矩阵乘法。注意不能往回走,可以把点对应成边就好了,1号点新对应一个0号边。

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 #define M 10000005
 4 #define LL long long
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7 inline int ra()
 8 {
 9     int x=0,f=1; char ch=getchar();
10     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
11     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
12     return x*f;
13 }
14 const int p=45989;
15 int head[155];
16 int n,m,t,a,b,sum,cnt;
17 struct Edge{
18     int to,next;
19 }e[305];
20 struct Maxtri{
21     int a[155][155];
22     Maxtri(){
23         memset(a,0,sizeof(a));
24     }
25     friend Maxtri operator * (Maxtri a, Maxtri b) 
26     {
27         Maxtri ans;
28         for (int i=0; i<=cnt; i++)
29             for (int j=0; j<=cnt; j++)
30                 for (int k=0; k<=cnt; k++)    
31                     (ans.a[i][j]+=a.a[i][k]*b.a[k][j]%p)%=p;
32         return ans;
33     }
34     friend Maxtri operator ^ (Maxtri a, int b)
35     {
36         Maxtri ans;
37         for (int i=0; i<=cnt; i++) ans.a[i][i]=1;
38         for (;b;b>>=1,a=a*a)
39             if (b&1) ans=ans*a;
40         return ans;
41     }
42 };
43 Maxtri ans,A;
44 void insert(int x, int y){
45     e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;
46 }
47 int main()
48 {
49     n=ra(); m=ra(); t=ra(); a=ra()+1; b=ra()+1;
50     for (int i=1; i<=m; i++)
51     {
52         int x=ra()+1,y=ra()+1;
53         insert(x,y); insert(y,x);
54     }
55     for (int i=head[a];i;i=e[i].next)
56         ans.a[0][i]++;
57     for (int i=1; i<=cnt; i++)
58         for (int j=head[e[i].to];j;j=e[j].next)
59             if (j!=i+((i&1)?1:-1)) A.a[i][j]++;
60     A=A^(t-1); ans=ans*A;
61     for (int i=1; i<=cnt; i++)
62         if (e[i].to==b)
63             (sum+=ans.a[0][i])%=p;
64     cout<<sum;
65     return 0;
66 }

 

posted @ 2017-02-21 21:28  ws_ccd  阅读(205)  评论(0编辑  收藏  举报