2018.3.4 st

    5、生成树(st.cpp) 
 
题目描述 【题目背景】 LLJ 热愛生成树。 【题目描述】 给出一个结点数为 N 的无向完全图,即任意结点两两相连,且每条边长为 1。LLJ 想知道这 个图的生成树个数。 但这个数量太大了,LLJ 会懒得看,所以他只想看这个数量模 K 后的结果(若 K=0,输出-1 即 可) 注:生成树定义:在图中节点数为 N,边数为 N-1 的连通子图。 输入 输入共一行,两个非负整数 N K; 
 
输出 输出共一行一个整数,即方案数模 K 后的结果。 
 
样例输入 样例输入 1 1 10 
 
样例输入 2 4 13 
 
样例输入 3 100 23   
 
样例输出 样例输出 1 1 
 

样例输出 2 3 

分界线---------------------------------------------------------------------------------------------------------------------------

热爱生成树,啧。

这是一道找规律 + 快速幂的题,主要考数学。

规律怎么来的? 写出来看出来的。

转一个题解:

    T2生成树题解

求 N个结点的无向无权完全图的生成树总个数。 这种题可以尝试找规律(适当排列组合可以加快这个过程):

 当有1个结点时,有1个1×1 

当有2个结点时,有1个1×1 

当有3个结点时,有3个1×3 

当有4个结点时,有16个4×4 

当有5个结点时,有125个5×5×5 

那很容易发现,有n个结点时,有n^(n-2)个生成树(nn-2) 那么90分算法就出来了:O(n)时间算出n^(n-2) 观察到100分时0≤N≤1E18,O(n)肯定会爆,所以需要快速幂,可以达到 O(Log n)的时间。 注意到N为0或1时,需要特判: N等于0时,肯定没有生成树(想想-1条边),此时应该输出0,如果用某些方 法让快速幂不爆炸(如判断指数是否大于  0),如  X*的程序,可能输出1。 N等于1时,只有一个生成树,但此时求的是1-1,快速幂因为有负的指数, 如果快速幂使用右移可能会出错,所有要使用div 2或特判。 本题还设置了一个K等于0的点,如果不特判也会因模0而RE。但也有一 些人因此拿了  10  分。 注意最后的点,因为数据范围开到了long long/int64,所以快速幂也应更 改,但要注意,底数先要模K再进行快速幂!!!不然会爆longlong/int64!

#include<bits/stdc++.h>
using namespace std;
long long n,MOD;
long long Pow(long long a,long long b)
{
long long ans = 1;
while(b)
{
if(b & 1)
ans = ans * a % MOD;
a = a * a % MOD;
b >>= 1; 
}
return ans;
}
int main()
{
cin >> n >> MOD;
if(MOD == 0)
{
printf("%d",-1);
}
else if(n == 1)
{
printf("%d",1);
}
else if(n == 0)
{
printf("%d",0);
}
else{
printf("%lld",Pow(n % MOD,n - 2));
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/chang_yl/article/details/79435454
ST
今日推荐