BZOJ4766 文艺计算姬

Description

"奋战三星期,造台计算机"。小W响应号召,花了三星期造了台文艺计算姬。文艺计算姬比普通计算机有更多的艺
术细胞。普通计算机能计算一个带标号完全图的生成树个数,而文艺计算姬能计算一个带标号完全二分图的生成树
个数。更具体地,给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图K_{n,m},计算姬能快
速算出其生成树个数。小W不知道计算姬算的对不对,你能帮助他吗?

Input

仅一行三个整数n,m,p,表示给出的完全二分图K_{n,m}
1 <= n,m,p <= 10^18

Output

仅一行一个整数,表示完全二分图K_{n,m}的生成树个数,答案需要模p。

Sample Input

2 3 7

Sample Output

5
显然可以用矩阵树定理,但是是$O(n^3)$
显然这道题是不行的
考虑打表,附上打表程序
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long lol;
 8 int a[301][301],Mod=1e9+7,n,m,ans;
 9 char s[301][301];
10 void guass()
11 {int i,j,k;
12   n=n+m-1;
13   ans=1;
14   for (i=1;i<=n;i++)
15     {
16       for (j=1;j<=n;j++)
17     {
18       a[i][j]=(a[i][j]+Mod)%Mod;
19     }
20     }
21   for (i=1;i<=n;i++)
22     {
23       for (j=i+1;j<=n;j++)
24     {
25       while (a[j][i])
26         {
27           int t=a[i][i]/a[j][i];
28           for (k=i;k<=n;k++)
29         {
30           a[i][k]=(a[i][k]-1ll*t*a[j][k]%Mod+Mod)%Mod;
31           swap(a[i][k],a[j][k]);
32         }
33           ans*=-1;
34         }
35     }
36       ans=1ll*ans*a[i][i]%Mod;
37     }
38   ans=(ans+Mod)%Mod;
39 }
40 int main()
41 {int i,j;
42   cin>>n>>m>>Mod;
43   for (i=1;i<=n;i++)
44     {
45       for (j=n+1;j<=n+m;j++)
46     {
47       a[i][j]--;a[j][i]--;
48       a[i][i]++;a[j][j]++;
49     }
50     }
51   guass();
52   cout<<n+1-m<<' '<<m<<' '<<ans;
53 }
View Code矩阵树

分解因数后发现

$ans=n^{m-1}*m^{n-1}$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long lol;
 8 lol ans1,ans2,n,m,Mod,ans;
 9 lol qadd(lol x,lol y)
10 {
11   lol res=0;
12   while (y)
13     {
14       if (y&1)
15     {
16       res=(res+x);
17       if (res>=Mod) res-=Mod;
18     }
19       x=(x+x);
20       if (x>=Mod) x-=Mod;
21       y>>=1;
22     }
23   return res;
24 }
25 lol qpow(lol x,lol y)
26 {
27   lol res=1;
28   while (y)
29     {
30       if (y&1) res=qadd(res,x);
31       x=qadd(x,x);
32       y>>=1;
33     }
34   return res;
35 }
36 int main()
37 {
38   cin>>n>>m>>Mod;
39   ans1=qpow(n,m-1);
40   ans2=qpow(m,n-1);
41   ans=qadd(ans1,ans2);
42   cout<<ans;
43 }

 

posted @ 2018-03-16 20:37  Z-Y-Y-S  阅读(280)  评论(0编辑  收藏  举报