BZOJ2467 [中山市选2010]生成树

Description

有一种图形叫做五角形圈。一个五角形圈的中心有1个由n个顶点和n条边组成的圈。在中心的这个n边圈的每一条边同时也是某一个五角形的一条边,一共有n个不同的五角形。这些五角形只在五角形圈的中心的圈上有公共的顶点。如图0所示是一个4-五角形圈。
 
现在给定一个n五角形圈,你的任务就是求出n五角形圈的不同生成树的数目。还记得什么是图的生成树吗?一个图的生成树是保留原图的所有顶点以及顶点的数目减去一这么多条边,从而生成的一棵树。
注意:在给定的n五角形圈中所有顶点均视为不同的顶点。

Input

输入包含多组测试数据。第一行包含一个正整数T,表示测试数据数目。每组测试数据包含一个整数n( 2<=N<=100),代表你需要求解的五角形圈中心的边数。

 

Output

对每一组测试数据,输出一行包含一个整数x,表示n五角形圈的生成树数目模2007之后的结果。

Sample Input

1
2

Sample Output

40

 

正解:快速幂+数学推导

解题报告:

  详细题解传送门:http://blog.csdn.net/PoPoQQQ/article/details/41348131

  我的组合数学还是太弱了。。。

  不管怎么拆边,都会发现发现这个环上任意拆掉一条边都会导致某个五边形被拆掉两条边 且一条边在中心多边形上
  于是可知 这个图成为一棵树当且仅当一个五边形被拆掉两条边 剩余五边形被拆掉一条边 且被拆掉两条边的五边形拆掉的其中一条边在中心多边形上
  拆掉两条边的五边形有n个可以选 第一条边拆掉中心多边形上的 第二条边有4条可以选
  其余的五边形每个可以拆掉一条边 方案数5^(n-1)
  故最终方案数为4n*5^(n-1)

  直接快速幂处理一下就可以了。

 

 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 #ifdef WIN32   
14 #define OT "%I64d"
15 #else
16 #define OT "%lld"
17 #endif
18 using namespace std;
19 typedef long long LL;
20 const int MOD = 2007;
21 int n,ans;
22 
23 inline int getint()
24 {
25        int w=0,q=0;
26        char c=getchar();
27        while((c<'0' || c>'9') && c!='-') c=getchar();
28        if (c=='-')  q=1, c=getchar();
29        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
30        return q ? -w : w;
31 }
32 
33 inline int quickpow(int x,int y){
34     int base=1;
35     while(y) {
36     if(y&1) { base*=x; base%=MOD; }
37     x*=x; x%=MOD;
38     y=y>>1;
39     }
40     return base;
41 }
42 
43 inline void work(){
44     int T=getint();
45     while(T--) {
46     n=getint(); ans=4*n;
47     if(ans>=MOD) ans%=MOD;
48     ans*=quickpow(5,n-1); 
49     if(ans>=MOD) ans%=MOD;
50     printf("%d
",ans);
51     }
52 }
53 
54 int main()
55 {
56   work();
57   return 0;
58 }
原文地址:https://www.cnblogs.com/ljh2000-jump/p/5761620.html