ZOJ 3688

做出这题,小有成就感

本来已打算要用那个禁位的排列公式,可是,问题在于,每个阶乘前的系数r的求法是一个难点。

随便翻了翻那本美国教材《组合数学》,在容斥原理一章的习题里竟有一道类似,虽然并无答案,但他的注意倒是提醒了我。不妨把那2*n个位置看成排成一个圆周的一列,从中选出k个不相邻的数的组合数。不过,经我验证,他上面的那道公式是错的,应该把n改成2*n才对。哈哈,问题就这样解决了。

在计组合数时,不妨使用全排列的公式,又由于100.。。0007是一个质数,所以可以使用费马小定理在处理各个阶乘除法时求得逆元。

解决。

#include <iostream>
#include <cstdio>
#include <algorithm>
#define MOD 1000000007
#define N 200005
using namespace std;

typedef long long LL;

LL f[N];

void initial(){
	f[0]=1;
	for(LL i=1;i<N;i++)
	f[i]=(f[i-1]*i)%MOD;
}

LL quick(LL p,LL r){
	LL ans=1;
	while(r){
		if(r&1)
		ans=(ans*p)%MOD;
		r>>=1;
		p=(p*p)%MOD;
	}
	return ans;
}

int main(){
	initial();
	int n;
	while(scanf("%d",&n)!=EOF){
		if(n<3){
			printf("0\n");
			continue;
		}
		LL ans=f[n];
		int s=2*n;
		for(int i=1;i<=n;i++){
			LL uper=((LL)s*f[s-i-1])%MOD;
			LL down=(f[s-2*i]*f[i])%MOD;
			down=quick(down,MOD-2);
			LL res=(((uper*down)%MOD)*f[n-i])%MOD;
			if(i&1){
				ans=((ans-res)%MOD+MOD)%MOD;
			}
			else ans=((ans+res)%MOD+MOD)%MOD;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

  

时间: 2024-12-30 19:31:12

ZOJ 3688的相关文章

zoj 3688 The Review Plan II 禁位排列 棋盘多项式 容斥

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4971 题意:共有N天和N个章节,每天完成一个章节,规定第i个章节不可以在第i天或者i+1天完成(第N个章节则是第N天和第1天不能),求分配能完成所有章节的方案数. 思路: 主要还是根据棋盘多项式的公式来求解: 但是这题和ZOJ3687不同,数据量N最大有100000,因此不能爆搜,需要推一下公式. 按照题意,先求禁位组成的棋盘的棋盘多项式,再用容斥.禁位组成的棋盘如

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an

zoj 2156 - Charlie&#39;s Change

题目:钱数拼凑,面值为1,5,10,25,求组成n面值的最大钱币数. 分析:dp,01背包.需要进行二进制拆分,否则TLE,利用数组记录每种硬币的个数,方便更新. 写了一个 多重背包的 O(NV)反而没有拆分快.囧,最后利用了状态压缩优化 90ms: 把 1 cents 的最后处理,其他都除以5,状态就少了5倍了. 说明:貌似我的比大黄的快.(2011-09-26 12:49). #include <stdio.h> #include <stdlib.h> #include <

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

ZOJ 3607 Lazier Salesgirl (贪心)

Lazier Salesgirl Time Limit: 2 Seconds      Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer a piece of bread for price pi. But she is so lazy

ZOJ - 2243 - Binary Search Heap Construction

先上题目: Binary Search Heap Construction Time Limit: 5 Seconds      Memory Limit: 32768 KB Read the statement of problem G for the definitions concerning trees. In the following we define the basic terminology of heaps. A heap is a tree whose internal n

ZOJ 2859 二维线段树

思路:自己写的第二发二维线段树1A,哈哈,看来对二维的push操作比较了解了:但是还没遇到在两个线段树中同时进行push操作的,其实这题我是想在x维和y维同时进行push操作的,但是想了好久不会,然后看到这题又给出10秒,然后想想在x维线段直接单点查询肯定也过了,然后在第二维就只有pushup操作,在第一维线段树没有pushup操作.要是在第一维也有pushup操作的话,那就不用单点查询那么慢了.不过也A了,想找题即在二维同时进行pushup和pushdown操作的. #include<iost

ZOJ 2588

求一个无向图的桥(可能存在重边),输出割边的数目,并按顺序输出割边的序号(输入的顺序). 由于内存的限制 , 无法使用邻接矩阵 , 只能用邻接表了 . 第一次用了邻接表,超内存了: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <string.h> 5 using namespace std; 6 const int N=10002; 7 const i

ZOJ 2587 Unique Attack 判断最小割是否唯一

很裸的判断最小割是否唯一.判断方法是先做一遍最大流求最小割,然后从源点和汇点分别遍历所有能够到达的点,看是否覆盖了所有的点,如果覆盖了所有的点,那就是唯一的,否则就是不唯一的. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostr