BZOJ3792: 跑步

题解:

感觉被坑出翔。。。

显然我们把矩阵乘法中的点当成原图中的边就可以了。

先写opertor 在struct里面居然只能带一个变量?。。。

放到外面,然后还得加引用?

然后题目描述不清,重边怎么算?好吧,后来知道重边算两条。

然后没开ll,没取模各贡献一次WA。。。

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 500
14 #define maxm 500+100
15 #define eps 1e-10
16 #define ll long long
17 #define pa pair<int,int>
18 #define for0(i,n) for(int i=0;i<=(n);i++)
19 #define for1(i,n) for(int i=1;i<=(n);i++)
20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
22 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
23 #define mod 45989
24 using namespace std;
25 inline ll read()
26 {
27     ll x=0,f=1;char ch=getchar();
28     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
29     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
30     return x*f;
31 }
32 int n,m,s,tot,cnt,num[maxn],c[maxn][2];
33 struct matrix
34 {
35     int d[maxn][maxn];
36     matrix(){memset(d,0,sizeof(d));}
37 }a,b;
38 inline matrix operator *(matrix &x,matrix &y)
39 {
40     matrix z;
41     for1(i,m)
42      for1(j,m)
43       for1(k,m)
44        (z.d[i][j]+=x.d[i][k]*y.d[k][j])%=mod;
45     return z;
46 }
47 inline void print(matrix x)
48 {
49     for1(i,m)for1(j,m)cout<<i<<' '<<j<<' '<<x.d[i][j]<<endl;
50 }
51 void ksm(ll y)
52 {
53     for(;y;y>>=1,a=a*a)
54      if(y&1)b=b*a;
55 }
56 int main()
57 {
58     freopen("input.txt","r",stdin);
59     freopen("output.txt","w",stdout);
60     n=read();m=read();s=read();ll q=read();tot=1;
61     for1(i,m)
62     {
63         int x=read(),y=read();
64         c[++tot][0]=x;c[tot][1]=y;
65         c[++tot][0]=y;c[tot][1]=x;
66     }
67     m=tot;
68     for1(i,m)for1(j,m)if(i!=j&&i!=(j^1)&&c[i][1]==c[j][0])a.d[i][j]=1;
69     for1(i,m)b.d[i][i]=1;
70     ksm(q-1);
71     for1(i,m)if(c[i][0]==s)num[++cnt]=i;
72     for1(i,n)
73     {
74         int ans=0;
75         for1(j,m)if(c[j][1]==i)
76         for1(k,cnt)(ans+=b.d[num[k]][j])%=mod;
77         printf("%d\n",ans);
78     }
79     return 0;
80 }
View Code

3792: 跑步

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 48  Solved: 21
[Submit][Status]

Description

小白非常喜欢跑步,所以他经常在校园内跑步(其实是想看美女~)。校园可以看成由N个地区,由M个道路连接。我们小白早上从一个地点出发,但是不知道怎么跑才好。小白有个习惯,不会沿着刚刚经过的道路再返回(比如从A到B经过C道路,下一次,不会再沿着C从B返回A)。
小白想知道从他出发的地点,经过Q条路,到达每个点的方案数。这样方便他去选择。

Input

第一行3个整数N,M,S,Q。表示有N个地区,M条道路,从S出发,需要经过Q条路。
下面M行,每行两个整数表示A,B之间有条道路。

Output

一共N行,每行一个整数表示从S到I的方案数(mod 45989)

Sample Input

10 20 9 10
1 5
5 10
10 4
10 2
10 7
4 3
10 9
2 8
5 6
6 1
2 10
4 7
9 10
9 6
7 3
7 3
7 2
1 8
9 7
4 5

Sample Output

17420
41928
35701
40814
31937
22933
5754
15848
43620
10819

HINT

 

N<=30 M<=60 Q<=10^16

posted @ 2014-12-20 11:50  ZYF-ZYF  Views(227)  Comments(0Edit  收藏  举报