P2817 宋荣子的城堡
P2817 宋荣子的城堡
一道找规律的题,现在深入追究发现了有趣的东西。
1 1
2 2
3 9
4 64
显然k^(k-1) 在日照的时候也推出来了。
3 9今天推错了,要列出所有的情况,然后再选,否则会漏掉。
答案是(k^(k-1)) * ((n-k)^(n-k))
对了,我卡速米一直打的是错的。要对指数为0的情况特判,不然会死循环。
现在,告诉我,why?
cayley定理(凯莱定理)
对于有n个节点,生成树的方案有多少种?
答案是n^(n-2)
推导过程如下:
k表示现在有多少子树
显然初始时,k==n
现在从n个节点中任选1个,有C(n 1)种可能,再从不包含这个节点的子树中选1个子树和这个节点连起来,有C(k-1 1),然后子树减少一个。重复这个过程直到,子树只剩1个,乘法原理,(n^(n-1))*(n-1)!。
假定每次都是(从n个节点中任选1个)选的同一个,并把它设成根,想象一下,对于同一棵树这就考虑了每个节点是根的情况。
有n-1条边,不考虑加进来的顺序,所以再除(n-1)!,现在成了n^(n-1),在一棵树中,根节点是哪个都无所谓,再除n,就成了
n^(n-2)。
但是对于这个题而言,可以假定1连向的点为根节点,实际上把它的每个点当成根节点都会形成新的方案,所以再*k
故答案 k^(k-1)
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<cstring> 8 #define mod 1000000007 9 #define inf 2147483647 10 #define For(i,a,b) for(register long long i=a;i<=b;i++) 11 #define p(a) putchar(a) 12 #define g() getchar() 13 //by war 14 //2017.10.19 15 using namespace std; 16 long long n,k; 17 void in(long long &x) 18 { 19 long long y=1; 20 char c=g();x=0; 21 while(c<'0'||c>'9') 22 { 23 if(c=='-') 24 y=-1; 25 c=g(); 26 } 27 while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); 28 x*=y; 29 } 30 void o(long long x) 31 { 32 if(x<0) 33 { 34 p('-'); 35 x=-x; 36 } 37 if(x>9)o(x/10); 38 p(x%10+'0'); 39 } 40 41 long long POW(long long a,long long b) 42 { 43 a%=mod; 44 if(b==0) 45 return 1; 46 while(b%2==0) 47 { 48 a=(a*a)%mod; 49 b>>=1; 50 } 51 long long r=1; 52 while(b>0) 53 { 54 if(b%2==1) 55 r=(r*a)%mod; 56 a=(a*a)%mod; 57 b>>=1; 58 } 59 return r; 60 } 61 62 int main() 63 { 64 in(n),in(k); 65 // n%=mod; 66 o((POW(k,k-1)*POW(n-k,n-k))%mod); 67 return 0; 68 }