2019.01.30【NOIP提高组】模拟 B 组

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/86705867

JZOJ 4252 QYQ的图(深搜)


JZOJ 4248 n染色

题目

给一个 n n 边形涂色,共有 m m 种颜色的笔,使相邻两边颜色不同的方案有多少


分析

设答案为 f [ n ] f[n] ,那么分类讨论新加进来的第 n n 条边

  • 当两条邻边相同时,那么等同于在 n 2 n-2 条边内加入一条相同的边和一条不同的边,那也就是 f [ n 2 ] × ( m 1 ) f[n-2]\times(m-1)
  • 当两条邻边不同时,也就是在 n 1 n-1 条边内加入一条与两条邻边都不同的边,那也就是 f [ n 1 ] × ( m 2 ) f[n-1]\times (m-2)

综上所述, f [ n ] = f [ n 2 ] × ( m 1 ) + f [ n 1 ] × ( m 2 ) f[n]=f[n-2]\times(m-1)+f[n-1]\times(m-2)
那考虑优化,首先可以矩阵乘法~~,但是这道题不需要~~
那可以简化这条式子
f [ n ] + f [ n 1 ] = f [ n 1 ] × ( m 2 ) + f [ n 2 ] × ( m 1 ) + f [ n 1 ] = ( f [ n 1 ] + f [ n 2 ] ) × ( m 1 ) f[n]+f[n-1]=f[n-1]\times(m-2)+f[n-2]\times(m-1)+f[n-1]=(f[n-1]+f[n-2])\times(m-1)
那就可以得到 f [ n ] + f [ n 1 ] = ( m 1 ) n m f[n]+f[n-1]=(m-1)^nm
( f [ n ] + f [ n 1 ] ) ( f [ n 1 ] + f [ n 2 ] ) ± ± ( f [ 1 ] f [ 0 ] = m ) = f [ n ] (f[n]+f[n-1])-(f[n-1]+f[n-2])\pm\dots\pm(f[1]-f[0]=m)=f[n]
解开后用等比数列求和即可


代码

#include <cstdio>
#define rr register
using namespace std;
typedef long long ll; const ll mod=1000000007;
ll ans,n,m;
inline ll ksm(ll x,ll y){
	rr ll ans=1;
	for (;y;y>>=1,x=(x*x)%mod)
	    if (y&1) ans=(ans*x)%mod;
	return ans;
}
signed main(){
	freopen("color.in","r",stdin);
	freopen("color.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	ans=(m-1)*((n&1)?-1:1)+ksm(m-1,n%(mod-1));
	return !printf("%lld",ans%mod);
} 

JZOJ 4249 游戏(贪心)


猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/86705867