20140709 testC 数学题

考试时觉得AB题不可做后就开始写C题

结果C题缩点之后就不知道怎么计算了

想了三个小时还是没想出解

看了题解还是蛮简单

当时数学规律没找到

ans=N^(K-2)*Sum[1]*Sum[2]*….Sum[K]

K是联通块的个数 Sum[i]表示第i个连同快的个数

注意 k=1 时 ans=1 而不是 0

有两个 k=1 的点调了很久问了别人才知道应该输 1 >_<

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define N 100010
 6 typedef long long LL;
 7 
 8 LL p[N];
 9 int par[N];
10 int _rank[N];
11 LL mod;
12 
13 bool cmp(int a,int b) {
14     return a<b;
15 }
16 
17 void init(int n) {
18     for (int i=1;i<=n;i++) {
19         par[i]=i;
20         _rank[i]=0;
21     }
22 }
23 
24 int find(int x) {
25     if (par[x]==x) return x;
26     return par[x]=find(par[x]);
27 }
28 
29 void unite(int x,int y) {
30     x=find(x); y=find(y);
31     if (_rank[x]<_rank[y]) par[x]=y;
32     else {
33         par[y]=x;
34         if (_rank[x]==_rank[y]) _rank[x]++;
35     }
36 }
37 
38 bool same(int x,int y) {
39     return find(x)==find(y);
40 }
41 
42 void _swap(int &a,int &b) {
43     int t=a; a=b; b=t;
44 }
45 
46 void power(LL &a,LL b,int t) {
47     if (t==0) return ;
48     for (int i=1;i<=t;i++) {
49         a=a*b%mod;
50     }
51 }
52 
53 int main() {
54     LL n,m;
55     scanf("%lld%lld%lld",&n,&m,&mod);
56     init(n);
57     for (int i=0;i<m;i++) {
58         int u,v;
59         scanf("%d%d",&u,&v);
60         if (!same(u,v)) unite(u,v);
61     }
62     for (int i=1;i<=n;i++) par[i]=find(par[i]);
63     sort(par+1,par+1+n,cmp);
64     int k=0;
65     for (int i=1;i<=n;i++) {
66         k++;
67         p[k]=1;
68         while (par[i]==par[i+1]) {
69             p[k]++;
70             i++;
71         }
72     }
73     if (k==1) {
74         printf("1");
75         return 0;
76     }
77     LL ans=1;
78     for (int i=1;i<=k;i++) {
79         ans=ans*p[i]%mod;
80     }
81     power(ans,n,k-2);
82     printf("%lld",ans%mod);
83 }
View Code

 

posted @ 2014-07-10 13:13  __fjm  阅读(138)  评论(0编辑  收藏  举报