CodeForces 340E Iahub and Permutations

容斥原理,组合数。

找出有$cnt$个数字还有没放,那么总方案数就是$cnt!$。

总方案数里面包含了正确的和非正确的,我们需要将非正确的删去。

先删去$1$个数字$a[i]=i$的情况,发现会多删,要加回两个数字$a[i]=i$的情况,发现会多加......就是一个容斥原理的过程。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar(); x = 0;while(!isdigit(c)) c = getchar();
    while(isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar();  }
}

const int maxn=2010;
LL c[maxn][maxn],f[maxn];
LL mod=1e9+7;
int n,a[maxn],h[maxn];

LL MOD(LL a)
{
    if(a>=0) return a%mod;
    LL ff=(-a)/mod+1; a=a+ff*mod;
    return a%mod;
}

int main()
{
    for(int i=0;i<=2000;i++) c[i][0]=1;
    for(int i=1;i<=2000;i++)
        for(int j=1;j<=i;j++)
            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    f[0]=1; for(int i=1;i<=2000;i++) f[i]=(LL)i*f[i-1]%mod;

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=-1) h[a[i]]=1;
    }

    int cnt=0; for(int i=1;i<=n;i++) if(a[i]==-1) cnt++;

    int sum=0;
    for(int i=1;i<=n;i++)
    {
        if(h[i]) continue;
        if(a[i]!=-1) continue;
        sum++;
    }

    LL ans=f[cnt]; LL d=-1;
    for(int i=1;i<=sum;i++)
    {
        LL tmp=MOD(d*c[sum][i]*f[cnt-i]);
        ans=(ans+tmp)%mod; d=-d;
    }

    printf("%lld\n",ans);
    return 0;
}
时间: 2024-11-01 06:51:33

CodeForces 340E Iahub and Permutations的相关文章

codeforces 340E Iahub and Permutations(错排or容斥)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Iahub and Permutations 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 import

CodeForces 340E Iahub and Permutations 错排dp

Iahub and Permutations 题解: 令 cnt1 为可以没有限制位的填充数字个数. 令 cnt2 为有限制位的填充数字个数. 那么:对于cnt1来说, 他的值是cnt1! 然后我们对cnt2进行dp. 对于任意一个新加进来的数字,我们可以令一个一个没有限制位数放在这里, 那么新加进来的数字 ≍ 没有限制位, 他的方案为 i-1 * dp[i-1] , 然后我们如果把这个数字放到有限制位的数来说, 那么他的转移方程就和错排一样了. 代码: #include<bits/stdc++

codeforces A. Slightly Decreasing Permutations 题解

Permutation p is an ordered set of integers p1,??p2,??...,??pn, consisting of n distinct positive integers, each of them doesn't exceed n. We'll denote the i-th element of permutation p as pi. We'll call number n the size or the length of permutation

Codeforces D. Iahub and Xors

题目大意:给定一个N*N的区间,1:对(x0,y0,x1,y1)每个直 都xor v: 2: 求(x0,y0,x1,y1)区间的 sum xor: http://codeforces.com/blog/entry/8755 算得上经典题: 1 #include<stdio.h> 2 #include<algorithm> 3 #include<math.h> 4 #include<vector> 5 #include<string.h> 6 #i

CODEFORCES Rockethon 2015 B. Permutations

You are given a permutation p of numbers 1,?2,?-,?n. Let's define f(p) as the following sum: Find the lexicographically m-th permutation of length n in the set of permutations having the maximum possible value of f(p). Input The single line of input

Codeforces 463D Gargari and Permutations(求k个序列的LCS)

题目链接:http://codeforces.com/problemset/problem/463/D 题目大意:给你k个序列(2=<k<=5),每个序列的长度为n(1<=n<=1000),每个序列中的数字分别为1~n,求着k个序列的最长公共子序列是多长?解题思路:由于每个序列的数字分别为1~n即各不相同,所以可以用pos[i][j]记录第i个序列中j的位置.设dp[i]表示以i结尾的最长公共子序列长度,那么我们可以按顺序遍历第一个序列的位置i,再在第一个序列中枚举位置j(j<

Codeforces 987E Petr and Permutations(数组的置换与复原 、结论)

题目连接: Petr and Permutations 题意:给出一个1到n的序列,Petr打乱了3n次,Um_nik打乱了7n+1次,现在给出被打乱后的序列,求是谁打乱的. 题解:因为给出了一个3*n和一个7*n+1,发现这两个当一个为奇数另一个一定为偶数,所以可以联想和奇偶性质有关.但是这里面要算最短几步能把当前的序列变成1-n.这里我算错~~顺便学了一下如何将置换序列复原. #include<bits/stdc++.h> using namespace std; typedef pair

[树状数组][权值线段树] Codeforces 1093E Intersection of Permutations

题目描述 You are given two permutations aa and bb , both consisting of nn elements. Permutation of nn elements is such a integer sequence that each value from 11 to nn appears exactly once in it. You are asked to perform two types of queries with them: 1

CodeForces 501D Misha and Permutations Summation

题意: n(2*10^5)个元素的排列有n!种  用Perm(x)表示字典序第x的序列(从0开始)  用Ord(排列y)表示排列y的字典序  现在输入排列p和q  求  Perm([Ord(p)+Ord(q)]%n!) 思路: 容易想到  对于第i位p[i]  如果它是第d小的数字  那么说明比它小的d-1个数字所产生的全排列都已经计数过了 例子  35142  第4位是4  它是第2小的(1和3出现过了)  那么35124这种情况一定已经计数了 因此我们可以分别对于p和q找出序列是排第几的