Codeforces 题目传送门 & 洛谷题目传送门

upd on 2021.10.20:修了个 typo(

这是一道 *2600 的 D2E,然鹅为啥我没想到呢?wtcl/dk

首先第一步我就没想到/kk,看到“恰好”二字我们可以想到一个东西叫做二项式反演(qwq 这个套路在刷多项式题时经常见到,可咋换个场景就想不到了呢?显然是我多项式白学了/doge)。我们设 \(f_k\) 表示恰好 \(k\) 个完美数的排列个数,\(g_k\) 表示钦定 \(k\) 个位置满足 \(|p_i-i|=1\),剩下随便乱填的方案数,那么显然对于某个有 \(x\) 个完美位置的排列,它被计入 \(g_y(y<x)\) 的次数为 \(\dbinom{x}{y}\)。

也就是说 \(g_k=\sum\limits_{i=k}^nf_i\dbinom{i}{k}\)​。反演一下可得 \(f_k=\sum\limits_{i=k}^n(-1)^{i-k}\dbinom{i}{k}g_i\)​。

故我们只需求出 \(g_i\) 就行了。

怎么求 \(g_i\) 呢?这时候就要用到 DP 了,我们设 \(dp_{i,j,x,y}\) 表示填好了前 \(i\) 个位置,钦定了 \(j\) 个位置满足 \(|p_i-i|=1\),\(x\) 表示 \(i\) 是否被选择,\(y\) 表示 \(i+1\) 是否被选择(这一步我又没想到,看来我 DP 也白学了/ww)。转移就分 \(i\) 不是被钦定为“完美位置”,\(p_i=i+1,p_i=i-1\) 三种情况转移即可,具体来说:

  • \(dp_{i,j,0,0}=dp_{i-1,j,0,0}+dp_{i-1,j,1,0}+dp_{i-1,j-1,0,0}\)(放 \(i-1\) 或者不被钦定为完美位置)
  • \(dp_{i,j,0,1}=dp_{i-1,j-1,0,0}+dp_{i-1,j-1,1,0}\)(\(y=1\),只能放 \(i+1\))
  • \(dp_{i,j,1,0}=dp_{i-1,j,0,1}+dp_{i-1,j,1,1}+dp_{i-1,j-1,0,1}\)(放 \(i-1\) 或者不被钦定为完美位置)
  • \(dp_{i,j,1,1}=dp_{i-1,j-1,0,1}+dp_{i-1,j-1,1,1}\)(\(y=1\),只能放 \(i+1\))

初始 \(dp_{1,0,0,0}=dp_{1,1,0,1}=1\)。

最后 \(g_k=(dp_{n,k,0,0}+dp_{n,k,1,0})·(n-k)!\)(\(n+1\) 不能被选择),时间复杂度 \(n^2\)。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=1000;
const int MOD=1e9+7;
int n,m,dp[MAXN+5][MAXN+5][2][2];
int fac[MAXN+5],ifac[MAXN+5];
void add(int &x,int y){x+=y;if(x>=MOD) x-=MOD;}
int binom(int x,int y){return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;}
int main(){
scanf("%d%d",&n,&m);dp[1][1][0][1]=dp[1][0][0][0]=1;
fac[0]=1;ifac[0]=ifac[1]=1;
for(int i=2;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
for(int i=2;i<=n;i++) for(int j=0;j<=i;j++){
if(j){
add(dp[i][j][0][0],dp[i-1][j-1][0][0]);
add(dp[i][j][1][0],dp[i-1][j-1][0][1]);
add(dp[i][j][0][1],dp[i-1][j-1][0][0]);
add(dp[i][j][0][1],dp[i-1][j-1][1][0]);
add(dp[i][j][1][1],dp[i-1][j-1][0][1]);
add(dp[i][j][1][1],dp[i-1][j-1][1][1]);
}
add(dp[i][j][0][0],dp[i-1][j][0][0]);
add(dp[i][j][0][0],dp[i-1][j][1][0]);
add(dp[i][j][1][0],dp[i-1][j][0][1]);
add(dp[i][j][1][0],dp[i-1][j][1][1]);
} int ans=0;
for(int i=m;i<=n;i++){
int ways=1ll*(dp[n][i][0][0]+dp[n][i][1][0])*fac[n-i]%MOD;
if((i-m)&1) ans=(ans-1ll*ways*binom(i,m)%MOD+MOD)%MOD;
else ans=(ans+1ll*ways*binom(i,m))%MOD;
} printf("%d\n",ans);
return 0;
}

Codeforces 285E - Positions in Permutations(二项式反演+dp)的更多相关文章

  1. CodeForces - 285E: Positions in Permutations(DP+组合数+容斥)

    Permutation p is an ordered set of integers p1,  p2,  ...,  pn, consisting of n distinct positive in ...

  2. BZOJ3622 已经没有什么好害怕的了 二项式反演+DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3622 题解 首先显然如果 \(n - k\) 为奇数那么就是无解.否则的话,"糖果& ...

  3. CodeForces 340E Iahub and Permutations 错排dp

    Iahub and Permutations 题解: 令 cnt1 为可以没有限制位的填充数字个数. 令 cnt2 为有限制位的填充数字个数. 那么:对于cnt1来说, 他的值是cnt1! 然后我们对 ...

  4. Codeforces 285 E. Positions in Permutations

    \(>Codeforces \space 285 E. Positions in Permutations<\) 题目大意 : 定义一个长度为 \(n\) 的排列中第 \(i\) 个元素是 ...

  5. Codeforces 923E - Perpetual Subtraction(微积分+生成函数+推式子+二项式反演+NTT)

    Codeforces 题目传送门 & 洛谷题目传送门 神仙题 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 首先考虑最朴素的 \(dp\),设 \(dp_{z,i}\) 表示经 ...

  6. P4859 已经没有什么好害怕的了(dp+二项式反演)

    P4859 已经没有什么好害怕的了 啥是二项式反演(转) 如果你看不太懂二项式反演(比如我) 那么只需要记住:对于某两个$g(i),f(i)$ ---------------------------- ...

  7. 洛谷4859 BZOJ3622 已经没什么好害怕的了(DP,二项式反演)

    题目链接: 洛谷 BZOJ 题目大意:有两个长为 $n$ 的序列 $a,b$,问有多少种重排 $b$ 的方式,使得满足 $a_i>b_i$ 的 $i$ 的个数比满足 $a_i<b_i$ 的 ...

  8. BZOJ3622 已经没有什么好害怕的了 【dp + 二项式反演】

    题目链接 BZOJ3622 题解 既已开题 那就已经没有什么好害怕的了 由题目中奇怪的条件我们可以特判掉\(n - k\)为奇数时答案为\(0\) 否则我们要求的就是糖果大于药片恰好有\(\frac{ ...

  9. 51nod 1518 稳定多米诺覆盖(容斥+二项式反演+状压dp)

    [传送门[(http://www.51nod.com/Challenge/Problem.html#!#problemId=1518) 解题思路 直接算不好算,考虑容斥,但并不能把行和列一起加进去容斥 ...

随机推荐

  1. springboot读取配置文件中的信息

    在一个项目中,我们有时候会把一些配置信息写入到一个配置文件中,在java代码中读取配置文件的信息.在此记录下读取属性文件中的内容. 在springboot项目中,springboot的配置文件可以使用 ...

  2. mongodb的索引操作

    在mongodb中,当我们一个集合中的数据量非常大时,比如几百万条数据,如果不使用索引,对数据的查询就会进行全表扫描,这个时候查询的速度就会非常的慢,此时我们就需要为集合建立上索引,从而加快查询的速度 ...

  3. Go并发编程--Mutex/RWMutex

    目录 一.前言 二. Mutex 2.1 案例 三. 实现原理 3.1 锁的实现模式 3.2 Go Mutex 实现原理 3.2.1 加锁 3.2.2 解锁 四. 源码分析 4.1 Mutex基本结构 ...

  4. 替换空格 牛客网 剑指Offer

    替换空格 牛客网 剑指Offer 题目描述 请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20A ...

  5. 一次fork引发的惨案!

    "你还有什么要说的吗?没有的话我就要动手了",kill程序最后问道. 这一次,我没有再回答. 只见kill老哥手起刀落,我短暂的一生就这样结束了··· 我是一个网络程序,一直以来都 ...

  6. git与pycharm的使用详解(git+gitlab+pycham)

    前言 当自动化框架搭建出来后,需要多个人来使用框架,写自动化用例. 在这个阶段,我们不可能将写好的代码打包发给其他人,这样很麻烦,多人协作一点也不灵活. 这时候,就提现出了git的价值 一.下载安装 ...

  7. redhat 7.x 的防火墙软件firewall 介绍

    zone 的概念.firewall 一般有9个zone ,配置文件都在 /usr/lib/firewalld/zones/ 里面. 系统的配置文件目录就在 /usr/lib/firewalld 这个目 ...

  8. 理解前端blob和ArrayBuffer,前端接受文件损坏的问题

    1 downloadTemplate().then(res =>{ 2 3 const data = res.data 4 const url = window.URL.createObject ...

  9. Java 17 新功能介绍(LTS)

    点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. Jav ...

  10. OpenXml SDK学习笔记(1):Word的基本结构

    能写多少篇我就不确定了,可能就这一篇就太监了,也有可能会写不少. OpenXml SDK 相信很多人都不陌生,这个就是管Office一家的文档格式,Word, Excel, PowerPoint等都用 ...