【xsy2303】呀 dp
题目大意:你需要构造一个长度为$n$的排列$A$,使得里面包含有子序列$B$(子序列$B$为一个给定的$1$到$m$的排列),且对于每个$i$,有$A[A[i]]=i$,问有多少种方案方案。
数据范围:$n≤10^7$,$m≤500$,答案对$10^9+7$取模
我们首先不考虑有m的存在,考虑如何构造一个符合条件的序列$A$。
我们发现我们可以DP,设$f[i]$表示有多少种长度为i的序列满足$A[A[i]]=i$。
对于第$i$个数,我们可以考虑把它填在原位,或者放在第j个位置,然后在$A[i]$处填上$j$。
根据这个,不难推出$f[i]=(i-1)f[i-2]+f[i-1]$。
我们下面考虑,序列$B$的前$k$个数,位于$A$中前$m$个位置,剩余的$m-k$个,位于后$n-m$个位置。
我们发现,对于剩余的$m-k$个数,对应的$A_B[i]$,都会被占用,用来填(填写了$B[i]$的位置)。
所以我们需要在前$m$个位置里,用恰好$k$个位置,按顺序填出序列$B$前$k$个数字。
不难发现,至多只有一种填法。
对于$B[i]$,我们找到序列$A$中第i个可以填数的地方,直接填入$B[i]$即可。
最后$O(m)$扫一遍判断即可。
如果可行,那么剩下的$n-k$个位置中,需要找出$m-k$个位置放置$B[k+1],B[k+2].....B[m]$,并且在$A[B[k+1]]$等地方填上它们的位置。
剩下的$n-2m+k$个位置,就可以随便填>m的数了,方案数显然是$f[n-2m+k]$
所以方案数为$\binom{n-k}{m-k}\times f[n-2m+k]$。
我们对于每个不超过m的k全部处理一遍就可以了。
时间复杂度:$O(n+m^2)$
#include<bits/stdc++.h>
#define MOD 1000000007
#define L long long
#define M 10000005
using namespace std; L fac[M]={},invfac[M]={},f[M]={};
L pow_mod(L x,L k){L ans=;for(;k;k>>=,x=x*x%MOD) if(k&) ans=ans*x%MOD; return ans;}
L C(int n,int m){return fac[n]*invfac[m]%MOD*invfac[n-m]%MOD;} L mark[M]={},b[M]={},a[M]={},ans=,n,m;
void solve(int k){
if(n-m<m-k) return;
for(int i=,j=;i<=k;i++,j++){
while(!mark[j]) j++;
a[j]=b[i];
}
for(int i=;i<=m;i++)
if(mark[i]&&a[a[i]]!=i) return;
ans=(ans+C(n-m,m-k)*f[n-m-m+k])%MOD;
}
int main(){
fac[]=; for(int i=;i<M;i++) fac[i]=fac[i-]*i%MOD;
invfac[M-]=pow_mod(fac[M-],MOD-);
for(int i=M-;~i;i--) invfac[i]=invfac[i+]*(i+)%MOD;
f[]=f[]=; for(int i=;i<M;i++) f[i]=(f[i-]+f[i-]*(i-))%MOD; scanf("%d%d",&n,&m);
for(int i=;i<=m;i++) scanf("%d",b+i);
for(int k=;k<=m;k++){
mark[b[k]]=;
solve(k);
}
cout<<ans<<endl;
}
【xsy2303】呀 dp的更多相关文章
- BZOJ 1911: [Apio2010]特别行动队 [斜率优化DP]
1911: [Apio2010]特别行动队 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 4142 Solved: 1964[Submit][Statu ...
- 2013 Asia Changsha Regional Contest---Josephina and RPG(DP)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4800 Problem Description A role-playing game (RPG and ...
- AEAI DP V3.7.0 发布,开源综合应用开发平台
1 升级说明 AEAI DP 3.7版本是AEAI DP一个里程碑版本,基于JDK1.7开发,在本版本中新增支持Rest服务开发机制(默认支持WebService服务开发机制),且支持WS服务.RS ...
- AEAI DP V3.6.0 升级说明,开源综合应用开发平台
AEAI DP综合应用开发平台是一款扩展开发工具,专门用于开发MIS类的Java Web应用,本次发版的AEAI DP_v3.6.0版本为AEAI DP _v3.5.0版本的升级版本,该产品现已开源并 ...
- BZOJ 1597: [Usaco2008 Mar]土地购买 [斜率优化DP]
1597: [Usaco2008 Mar]土地购买 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4026 Solved: 1473[Submit] ...
- [斜率优化DP]【学习笔记】【更新中】
参考资料: 1.元旦集训的课件已经很好了 http://files.cnblogs.com/files/candy99/dp.pdf 2.http://www.cnblogs.com/MashiroS ...
- BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9812 Solved: 3978[Submit][St ...
- px、dp和sp,这些单位有什么区别?
DP 这个是最常用但也最难理解的尺寸单位.它与“像素密度”密切相关,所以 首先我们解释一下什么是像素密度.假设有一部手机,屏幕的物理尺寸为1.5英寸x2英寸,屏幕分辨率为240x320,则我们可以计算 ...
- android px转换为dip/dp
/** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public int dipTopx(Context context, float dpValue) { final floa ...
随机推荐
- 在网站中使用UEditor富文本编辑器
UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点. 官网链接 进入到下载页面,选择相应的版本下载 这里我们使用ASP.NET开发,所以选择 ...
- 第一章 C++语言入门
标准数据类型 C++语言提供了丰富的数据类型,如整数类型.实数类型(浮点数).字符类型等.每种数据类型均有均值范围,Dev-C++(4.9.9.2)是Windows平台 ...
- 20175314 实验一 Java开发环境的熟悉
20175314 实验一 Java开发环境的熟悉 一.实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用IDEA 编辑.编译.运行.调试Java程序. 3.完成实验,撰写实验报告,注意实 ...
- nodejs 箭头函数
背景 箭头函数,出现于ES6规范中. 使用 就是lambda函数. 一般使用: (a, b) => { return a + b; } 简略模式: 当参数只有一个时,可以省略括号:当返回值只有一 ...
- [leetcode]34.Find First and Last Position of Element in Sorted Array找区间
Given an array of integers nums sorted in ascending order, find the starting and ending position of ...
- Mysql——数据库和数据表的基本操作
/*创建数据库--- CREATE DATABASE 数据库名;*/ CREATE DATABASE itschool; /*查看已经存在的数据库*/ SHOW DATABASES; /*查看某个已创 ...
- PHP开发——常量
概念 l 常量就是值永远不变的量.如:圆周率.身份证号码等. l 所谓常量值永远不变的量,是指在一次完整的HTTP请求过程中. l 常量在程序运行过程中,不能修改.也不能删除. l 常量比变量 ...
- RN与webview通讯
一.RN给webview发送信息 this.webview.postMessage(message) 二.监听从React Native发过来的消息: window.document.addEven ...
- Java 7 使用TWR(Try-with-resources)完成文件copy
try-with-resources语句是声明了一个或多个资源的try语句块.在java中资源作为一个对象,在程序完成后必须关闭.try-with-resources语句确保每个资源在语句结束时关闭. ...
- MySQL数据库插入中文乱码解决方法
在mysql数据库中,插入中文数据时,会出现乱码的现象. 我的测试方法: 首先用Navicat for MySql 插入一行数据,带有中文的. 再用mysql命令行来查看插入的数据,看是否出现乱码. ...