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,因此不能爆搜,需要推一下公式。

按照题意,先求禁位组成的棋盘的棋盘多项式,再用容斥。禁位组成的棋盘如下:

rk(C)可以转化成求1-2*N组成的圆环中,取k个不相邻的数的不同方案数。

假设在圆环中先选择一个数字,那么还需2*N-3个数中选择k-1不相邻数,这时候圆环变成了一条直链。

那么根据在1~N数中选择k个不相邻的数的方案数的公式:

可以得出在1~(2*N-3)数中选择k-1个不相邻的数的方案数为:,化简得:

所以求1-2*N组成的圆环中,取k个不相邻的数的不同方案数的公式为:

然后根据容斥原理,本题的公式即为:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 100010
 4 long long num[maxn*2];
 5 const long long mod = 1e9+7;
 6 void init()
 7 {
 8     num[0] = 1; num[1] = 1;
 9     for(int i = 2; i < 2*maxn; i++)
10     {
11         num[i] = num[i-1]*i%mod;
12     }
13 }
14 int N;
15 long long quick_mod(long long a, long long b, long long mod)
16 {
17     long long ret = 1;
18     long long temp = a;
19     while(b)
20     {
21         if(b&1) ret = ret*temp%mod;
22         temp = temp*temp%mod;
23         b >>= 1;
24     }
25     return ret;
26 }
27 int main()
28 {
29    // freopen("in.txt", "r", stdin);
30     init();
31     while(~scanf("%d", &N))
32     {
33         if(N == 1 || N == 2)
34         {
35             printf("0\n"); continue;
36         }
37         long long ans = num[N];
38         long long a, b, temp;
39         for(int k = 1; k <= N; k++)
40         {
41             a = num[2*N-k-1]*2%mod*N%mod;
42             b = k*num[k-1]%mod*num[2*N-2*k]%mod;
43             b = quick_mod(b, mod-2, mod);
44             temp = a*b%mod*num[N-k];
45
46             if(k&1) ans = ((ans - temp)%mod + mod)%mod;
47             else ans = (ans + temp)%mod;
48         }
49         printf("%lld\n", ans);
50     }
51     return 0;
52 }
时间: 2024-10-27 06:31:42

zoj 3688 The Review Plan II 禁位排列 棋盘多项式 容斥的相关文章

zoj 3687 The Review Plan I 禁位排列 棋盘多项式

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3687 题意:有N天和N个章节,每天可以完成一个章节,有M个限制,表示第Di天不能完成章节Ci. 问共有多少种计划方案可以完成所有章节. 思路: 学习了一下棋盘多项式的知识 http://wenku.baidu.com/link?url=NXPYih0AzZJTi0Tqd4Qb91vq2Rz0f3YCm7IQpu0pcbPTlv75DeiVtTj81sDtqdnv

ZOJ 3687 The Review Plan I ( 禁位排列 + 容斥原理 )

ZOJ 3687 The Review Plan I ( 禁位排列 + 容斥原理 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 55566677 #define MAXN 55 LL fac[MAX

ZOJ 2688 The Review Plan II

https://zoj.pintia.cn/problem-sets/91827364500/problems/91827369470 题意: n天n个计划,一天完成一个计划,第i个计划不能在第i天和第i+1天完成,第n个计划不能在第n天和第1天完成,求安排计划的方案数. 有禁区的排列问题 在n*n有禁区棋盘上放n个棋子,每行每列只能放1个,第i行的禁区为第i和i+1列,第n行禁区为第n和1列 根据容斥原理,得 方案数=n! - r1(n-1)! + r2(n-2)! - …… ± rn 其中r

ZOJ 3687 The Review Plan I

The Review Plan I Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on ZJU. Original ID: 368764-bit integer IO format: %lld      Java class name: Main Michael takes the Discrete Mathematics course in this semester. Now it's close t

zoj 3557 How Many Sets II

How Many Sets II Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition: T is a subset of S |T| = m T does not contain continuous numbers

ZOJ 3688

做出这题,小有成就感 本来已打算要用那个禁位的排列公式,可是,问题在于,每个阶乘前的系数r的求法是一个难点. 随便翻了翻那本美国教材<组合数学>,在容斥原理一章的习题里竟有一道类似,虽然并无答案,但他的注意倒是提醒了我.不妨把那2*n个位置看成排成一个圆周的一列,从中选出k个不相邻的数的组合数.不过,经我验证,他上面的那道公式是错的,应该把n改成2*n才对.哈哈,问题就这样解决了. 在计组合数时,不妨使用全排列的公式,又由于100...0007是一个质数,所以可以使用费马小定理在处理各个阶乘除

zoj 3812 We Need Medicine (dp 位优化 巧妙记录路径)

We Need Medicine Time Limit: 10 Seconds      Memory Limit: 65536 KB      Special Judge A terrible disease broke out! The disease was caused by a new type of virus, which will lead to lethal lymphoedema symptom. For convenience, it was namedLL virus.

zoj——3557 How Many Sets II

How Many Sets II Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition: T is a subset of S |T| = m T does not contain continuous numbers

[LeetCode] 137. Single Number II (位运算)

传送门 Description Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one. Note:Your algorithm should have a linear runtime complexity. Could you implement it without using extra me