Codeforces Round #198 (Div. 2) E. Iahub and Permutations —— 容斥原理
题目链接:http://codeforces.com/contest/340/problem/E
1 second
256 megabytes
standard input
standard output
Iahub is so happy about inventing bubble sort graphs that he's staying all day long at the office and writing permutations. Iahubina is angry that she is no more important for Iahub. When Iahub goes away, Iahubina comes to his office and sabotage his research
work.
The girl finds an important permutation for the research. The permutation contains n distinct integers a1, a2,
..., an (1 ≤ ai ≤ n).
She replaces some of permutation elements with -1 value as a revenge.
When Iahub finds out his important permutation is broken, he tries to recover it. The only thing he remembers about the permutation is it didn't have any fixed point. A fixed point for a permutation is an element ak which
has value equal to k (ak = k).
Your job is to proof to Iahub that trying to recover it is not a good idea. Output the number of permutations which could be originally Iahub's important permutation, modulo 1000000007 (109 + 7).
The first line contains integer n (2 ≤ n ≤ 2000).
On the second line, there are n integers, representing Iahub's important permutation after Iahubina replaces some values with -1.
It's guaranteed that there are no fixed points in the given permutation. Also, the given sequence contains at least two numbers -1 and each positive number occurs in the sequence at most once. It's guaranteed that there is at least one suitable permutation.
Output a single integer, the number of ways Iahub could recover his permutation, modulo 1000000007 (109 + 7).
5
-1 -1 4 3 -1
2
For the first test example there are two permutations with no fixed points are [2, 5, 4, 3, 1] and [5, 1, 4, 3, 2]. Any other permutation would have at least one fixed point.
题意:
给出大小为n的序列,如果a[i] = k (1<=k<=n),则表明i位置被数字k占领了,如果a[i] = -1,则表明这个数字没有被占领。问:在这种情况下,有多少种错排方式?(题目输入保证有错排)
题解:
1.利用容斥原理计算出非法排列的个数, 非法排列即为至少有一个数是放在原位的, 即a[i] = i。
2.用全排列的个数减去非法排列的个数,即为答案。
容斥原理分析:
1.设m为空位数, k为可以放回原位的个数。
2.枚举可以放回原位的数的个数i,然后再对剩下可放的数进行排列。通式: C(k, i)*A(m-i, m-i):
2.1.当a需要放回原位时(其他有没放回原位不考虑), 那么剩下的数的排列有A(m-1, m-1); 对于 b、c等等, 也如此, 所以总数为C(k,1) * A(m-1, m-1); 根据容斥原理,奇数个时加上。
2.2.当a和b都需要放回原位时(其他有没放回原位不考虑), 那么剩下的数的排列有A(m-2, m-2);对于其他的两两组合也是一样, 所以总数为 C(k,2) * A(m-2, m-2); 根据容斥原理, 偶数个时减去。
2.3. 3个、4个、5个 …… k个。奇数个时加, 偶数个时减。
易错点:
1.凡是带有除法的式子, 都不能直接求模。
2.求模时, 若是加上负数, 需要: ans = (ans + mod)% mod 。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = 2e3+; bool val[maxn], pos[maxn];
LL C[maxn][maxn], A[maxn]; void init()
{
A[] = ; C[][] = ;
for(int i = ; i<maxn; i++)
{
A[i] = (1LL*i*A[i-])%mod;
C[i][] = ;
for(int j = ; j<=i; j++)
C[i][j] = (C[i-][j-] + C[i-][j])%mod;
}
} int main()
{
init();
int n, m, k;
while(scanf("%d",&n)!=EOF)
{
for(int i = ; i<=n; i++)
{
int x;
scanf("%d",&x);
if(x!=-)
val[x] = pos[i] = ;
} k = m = ;
for(int i = ; i<=n; i++)
{
if(!pos[i]) m++;
if(!pos[i] && !val[i]) k++;
} LL ans = A[m];
for(int i = ; i<=k; i++)
{
LL tmp = (1LL*C[k][i]*A[m-i])%mod;
ans -= (i&)?tmp:-tmp; //容斥原理
ans = (ans+mod)%mod;
}
cout<<ans<<endl;
}
}
Codeforces Round #198 (Div. 2) E. Iahub and Permutations —— 容斥原理的更多相关文章
- Codeforces Round #198 (Div. 1) D. Iahub and Xors 二维树状数组*
D. Iahub and Xors Iahub does not like background stories, so he'll tell you exactly what this prob ...
- Codeforces Round #198 (Div. 2)A,B题解
Codeforces Round #198 (Div. 2) 昨天看到奋斗群的群赛,好奇的去做了一下, 大概花了3个小时Ak,我大概可以退役了吧 那下面来稍微总结一下 A. The Wall Iahu ...
- Codeforces Round #485 (Div. 2) E. Petr and Permutations
Codeforces Round #485 (Div. 2) E. Petr and Permutations 题目连接: http://codeforces.com/contest/987/prob ...
- Codeforces Round #198 (Div. 2)
A.The Wall 题意:两个人粉刷墙壁,甲从粉刷标号为x,2x,3x...的小块乙粉刷标号为y,2y,3y...的小块问在某个区间内被重复粉刷的小块的个数. 分析:求出x和y的最小公倍数,然后做一 ...
- Codeforces Round #198 (Div. 2)E题解
E. Iahub and Permutations Iahub is so happy about inventing bubble sort graphs that he's staying all ...
- Codeforces Round #198 (Div. 1 + Div. 2)
A. The Wall 求下gcd即可. B. Maximal Area Quadrilateral 枚举对角线,根据叉积判断顺.逆时针方向构成的最大面积. 由于点坐标绝对值不超过1000,用int比 ...
- Codeforces Round #198 (Div. 2) D. Bubble Sort Graph (转化为最长非降子序列)
D. Bubble Sort Graph time limit per test 1 second memory limit per test 256 megabytes input standard ...
- [置顶] Codeforces Round #198 (Div. 1)(A,B,C,D)
http://codeforces.com/contest/341 赛后做的虚拟比赛,40分钟出了3题,RP爆发. A计数问题 我们可以对每对分析,分别对每对<a, b>(a走到b)进行统 ...
- Codeforces Round #198 (Div. 2) 340C
C. Tourist Problem time limit per test 1 second memory limit per test 256 megabytes input standard i ...
随机推荐
- 最简单的window下使用Jenkins来做自动化部署的教程
今天我们来说一下,如何使用Jenkins+powershell脚本,将我们的.NET CORE的脚本部署到对应的服务器上. 这里我们使用的源码管理工具是TFS.虽然源码管理器比较老旧,但是原理都差不多 ...
- 2016Unite Shanghai 总结
有幸参加了Unite 2016 Shanghai unity开发者大会,这里做一些简单总结 一.日本Marza 分享 <The Gift> Marza用unity做渲染,加上一些自己的扩展 ...
- 洛谷—— P1873 砍树
https://www.luogu.org/problemnew/show/P1873 题目描述 伐木工人米尔科需要砍倒M米长的木材.这是一个对米尔科来说很容易的工作,因为他有一个漂亮的新伐木机,可以 ...
- ubuntu下某些文件目录
1.#include <stdio.h> 2.#include <stdlib.h> stdio.h和stdlib.h的路径:/usr/include
- 如何使用ssh远程编辑定时任务crontab?
linxu定时任务使用crontab,编辑crontab可以直接编辑:crontab -e:也可以直接读取文件 crontab file.这两种操作都不需要特殊权限sudo.区别在于,crontab ...
- 我对Lamport Logical Clock的理解
建议先看论文原文再来看这篇文章,我不会对论文中的各个点都具体说明.仅仅是写一些我自己的想法,帮助理解. 大家都知道.分布式环境下.确定各个事件发生的顺序非常重要,不然就会发生一些麻烦的问题. 考虑一下 ...
- sql的一些知识
查询 查询表中的所有列(所有信息) SELECT * FROM userinfo 查询某一列(指定) select name from userinfo 查询某一列(指定,去重) SELECT DIS ...
- 【KMP】hdu1867(A + B for you again) 杭电java a题真坑
点击打开链接 Problem Description Generally speaking, there are a lot of problems about strings processing. ...
- PPAPI插件的动态创建、改动、删除
一旦你完毕了PPAPI插件的开发,实际使用时可能会有下列需求: 动态创建PPAPI插件 删除PPAPI插件 改变PPAPI插件的尺寸 实现起来非常easy,从JS里直接訪问DOM(BOM)就可以.以下 ...
- Java集合01----ArrayList的遍历方式及应用
Java集合01----ArrayList的遍历方式及应用 前面已经学习了ArrayList的源代码,为了学以 ...