ZOJ 3688 C The Review Plan II

据说是错排公式的扩展,叫做限位排列。递推公式如下:


但是因为对1000000007取了模,所以其中的除法不一定能除尽,当然在数学意义上是能够除尽的。可以用费马小定理去掉除法:

若P为质数,则 a^p = a mod P,即 a^(p-1) = 1 mod P。

但是这样一来式中会出现三项相乘,用long long计算是必须的,此外每乘一次要取模,否则long long也可能溢出。

这次是观赏了神奇的缩减行数的代码风格。。

#include <stdio.h>
#define Mod 1000000007
typedef unsigned long long ull;

unsigned int a[100001];

unsigned int exp(int a)
{
	unsigned int n = Mod - 2;
	ull x = a, r = 1;
	for( ; n; n>>=1)
	{
		if(n & 1) r = r*x%Mod;
		x = x*x%Mod;
	}
	return r%Mod;
}

int main()
{
	a[0]=a[3]=1, a[1]=a[2]=0, a[4]=2;
	for(int i=5; i<100001; ++i)
		a[i]=(i*(i-2ull)%Mod*a[i-1]%Mod+(ull)i*a[i-2]%Mod+(i&1?4:-4))%Mod*exp(i-2)%Mod;
	for(int j; ~scanf("%d",&j); printf("%u\n", a[j]));
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值