[bzoj2467][中山市选2010]生成树_快速幂

生成树 bzoj-2467 中山市选2010

题目大意题目链接

注释:略。


想法:首先,考虑生成树的性质。每两个点之间有且只有一条路径。我们将每个五边形的5条边分为外面的4条边和内部的一条边,在此简称为外边和内边。那么显然,每个五边形的4条外边至少需要选3条。

如果选了3条外边而且内边也没选,那么这个五边形就会被拆成两个部分。如果有2个五边形这么做,就会有两个部分之间直接断开,不符合生成树的定义。而且想让一个五边形和另一个五边形断开或者这个五边形从自身断开,只有这一种方案。如果没有任何一个五边形这么做那么所有点都在环内,仍然不符合生成树的定义。所以这样的五边形有且仅有一个。

考虑剩下的五边形。如果剩下的五边形没有任何一条边断开,这个五边形就是一个环,舍。而且每个五边形至多断开一条边,所以剩下的每个五边形都必须断开一条边。

接下来我们考虑证明每一个这样的方案都是合法的。首先,我们先把一个五边形的一条外边和一条内边断开。这样的话显然对于任何一个剩下的五边形:如果断开的是外边那么由内边和左右的五边形相连。如果断开的是内边那么有外边和左右的五边形相连。而且一个点像跨越一个只断开一条边的五边形只有一种方案,满足生成树性质,证毕。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 2007 
using namespace std;
typedef long long ll;
ll qpow(ll x,ll y)
{
	ll ans=1;
	while(y)
	{
		if(y&1) ans=(ans*x)%mod;
		y>>=1;
		x=(x*x)%mod;
	}
	return ans;
}
int main()
{
	int cases; cin >> cases ;
	while(cases--)
	{
		ll x; scanf("%lld",&x);
		printf("%lld
",4*x%mod*qpow(5,x-1)%mod);
	}
	return 0;
}

小结:对于这种题,我们一般的做法都是先考虑答案的形态,有奇效。

原文地址:https://www.cnblogs.com/ShuraK/p/9537293.html