Codeforces 285E Positions in Permutations (dp + 容斥)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <vector>
using namespace std;

#define N 1020
#define M 400030
#define mod 1000000007
#define B 234324
#define LL long long


int f[N][N][4];
int fac[N], nfac[N];

int F[N];

int n, k;
int qpow(int x, int k) {
	int ret = 1;
	while(k) {
		if(k & 1) ret = 1LL * ret * x % mod;
		k >>= 1;
		x = 1LL * x * x % mod;
	}
	return ret;
}
void add(int &x, int y) {
	x += y;
	if(x >= mod) x -= mod;
}
int C(int x, int y) {
	return 1LL * fac[x] * nfac[y] % mod * nfac[x-y] % mod;
}
void init() {
	fac[0] = 1; for(int i = 1; i < N; ++i) fac[i] = 1LL * fac[i-1] * i % mod;
	nfac[N-1] = qpow(fac[N-1], mod - 2);
	for(int i = N - 2; i >= 0; --i) nfac[i] = 1LL * nfac[i+1] * (i + 1) % mod;

	f[0][0][2] = 1;
	for(int i = 1; i <= n; ++i) {
		for(int j = 0; j < i; ++j) {
			for(int z = 0; z < 4; ++z) {
				if(z & 1) add(f[i][j+1][z/2+2], f[i-1][j][z]);
				if(i < n) add(f[i][j+1][z/2], f[i-1][j][z]);
				add(f[i][j][z/2+2], f[i-1][j][z]);
			}
		}
	}
	for(int i = 0; i <= n; ++i) {
		for(int z = 0; z < 4; ++z) {
			add(F[i], f[n][i][z]);
		}
		F[i] = 1LL * F[i] * fac[n-i] % mod;
	}
	for(int i = 0; i <= n; ++i) {
		int mul = -1;
		for(int j = i + 1; j <= n; ++j) {
			int tmp = 1LL * F[j] * C(j, i) % mod;
			tmp *= mul;
			if(tmp < 0) tmp += mod;
			add(F[i], tmp);
			mul = -mul;
		}
	}
}
int main() {
	cin >> n >> k;
	init();
	cout << F[k] << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值