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 }