BZOJ.4517.[SDOI2016]排列计数(错位排列 逆元)
错位排列\(D_n=(n-1)*(D_{n-1}+D_{n-2})\),表示\(n\)个数都不在其下标位置上的排列数。
那么题目要求的就是\(C_n^m*D_{n-m}\)。
阶乘分母部分的逆元可以线性处理,不需要扩欧。
//13516kb 6784ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define MAXIN 1000000
#define p (1000000007)
typedef long long LL;
const int N=1e6+5;
int inv_fac[N],fac[N],D[N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Init()
{
D[1]=0, inv_fac[0]=inv_fac[1]=fac[0]=fac[1]=D[0]=D[2]=1;
for(int i=2; i<N; ++i){
inv_fac[i]=1ll*(p-p/i)*inv_fac[p%i]%p,
fac[i]=1ll*fac[i-1]*i%p;
}
for(int i=3; i<N; ++i) inv_fac[i]=1ll*inv_fac[i]*inv_fac[i-1]%p;
for(int i=3; i<N; ++i) D[i]=1ll*(i-1)*(D[i-1]+D[i-2])%p;
}
int main()
{
Init();
int T=read(),n,m;
while(T--)
n=read(),m=read(),printf("%lld\n",(1ll*fac[n]*inv_fac[m]%p*inv_fac[n-m]%p*D[n-m]%p));
return 0;
}
考试时:这\(O(n^2)\)的\(70\)分不是送吗。。然后\(10^4\)的范围询问那么多,离线排个序 \(O(10^8)\) 3s很稳吧。。
然后写,发现不过样例。。发现主要是\(f[i][0]\)不对。比着dfs看,把规律找出来了:\(f[i][0]=(i-1)*f[i-1][0]+f[i-1][1]\)。(之前想漏个地方)
然后数据范围错了woc!是\(10^6\)。
然后就\(70\)分了。
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define MAXIN 1000000
#define mod (1000000007)
typedef long long LL;
const int N=1505;
int T,f[N+3][N+3],g[2][10005],Ans[500005];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Ques{
int x,y,id;
bool operator <(const Ques &a)const{
return x==a.x?y<a.y:x<a.x;
}
}q[500005];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Init()
{
LL tmp;
f[1][1]=f[2][0]=f[2][2]=1, f[1][0]=f[2][1]=0;
for(int i=3; i<N; ++i)
{
tmp=1ll*f[i-1][0]*(i-1)+(LL)f[i-1][1];
f[i][0]=(tmp%mod), f[i][i]=1;
for(int j=1; j<i; ++j)
{
tmp=1ll*f[i-1][j]*(i-j-1)+1ll*f[i-1][j+1]*(j+1)+(LL)f[i-1][j-1];
f[i][j]=(tmp%mod);
}
}
}
void Violence()
{
Init();
for(int i=1; i<=T; ++i) printf("%d\n",f[q[i].x][q[i].y]);
}
void Get_Ans(int n)
{
int pos=1;
while(q[pos].x==1) Ans[q[pos].id]=q[pos].y, ++pos;
while(q[pos].x==2) Ans[q[pos].id]=std::abs(1-q[pos].y), ++pos;
int now=1,las=0; LL tmp;
g[0][0]=g[0][2]=1, g[0][1]=0;
for(int i=3; i<=n; ++i)
{
tmp=1ll*g[las][0]*(i-1)+(LL)g[las][1];
g[now][0]=(tmp%mod), g[now][i]=1;
while(!(q[pos].y) && q[pos].x==i) Ans[q[pos].id]=g[now][0], ++pos;
for(int j=1; j<i; ++j)
{
tmp=1ll*g[las][j]*(i-j-1)+1ll*g[las][j+1]*(j+1)+(LL)g[las][j-1];
g[now][j]=(tmp%mod);
while(q[pos].y==j && q[pos].x==i) Ans[q[pos].id]=g[now][j], ++pos;
}
while(q[pos].y==i && q[pos].x==i) Ans[q[pos].id]=g[now][i], ++pos;
las=now, now^=1;
}
for(int i=1; i<=T; ++i) printf("%d\n",Ans[i]);
}
int main()
{
freopen("permutation.in","r",stdin);
freopen("permutation.out","w",stdout);
T=read();
int mx=0;
for(int i=1; i<=T; ++i) mx=std::max(mx,q[i].x=read()),q[i].y=read(),q[i].id=i;
if(mx<=1500) {Violence(); return 0;}
std::sort(q+1,q+1+T);
Get_Ans(mx);
fclose(stdin);fclose(stdout);
return 0;
}
BZOJ.4517.[SDOI2016]排列计数(错位排列 逆元)的更多相关文章
- [BZOJ4517][SDOI2016]排列计数(错位排列)
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1616 Solved: 985[Submit][Statu ...
- BZOJ 4517: [Sdoi2016]排列计数 错排+逆元
4517: [Sdoi2016]排列计数 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i, ...
- BZOJ 4517: [Sdoi2016]排列计数 [容斥原理]
4517: [Sdoi2016]排列计数 题意:多组询问,n的全排列中恰好m个不是错排的有多少个 容斥原理强行推♂倒她 $恰好m个不是错排 $ \[ =\ \ge m个不是错排 - \ge m+1个不 ...
- BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 911 Solved: 566[Submit][Status ...
- 数学(错排):BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 693 Solved: 434[Submit][Status ...
- BZOJ 4517: [Sdoi2016]排列计数 错排公式
4517: [Sdoi2016]排列计数 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4517 Description 求有多少种长度为 ...
- Bzoj 4517: [Sdoi2016]排列计数(排列组合)
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MB Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ...
- BZOJ 4517: [Sdoi2016]排列计数(组合数学)
题面 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m ...
- BZOJ 4517--[Sdoi2016]排列计数(乘法逆元)
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1727 Solved: 1067 Description ...
随机推荐
- dedecms在linux上安装提示没权限解决办法
web服务器运行的用户与目录所有者用户必须不一样,比如apache运行的用户为root,那么网站目录设置的所有者就应该不能设置为root,而是设置不同于root的用户,如apache. 我们这里假设w ...
- 【整理】HTML5游戏开发学习笔记(5)- 猜谜游戏
距上次学习笔记已有一个多月过去了,期间由于新项目赶进度,以致该学习计划给打断,十分惭愧.书本中的第六章的例子相对比较简单.所以很快就完成. 1.预备知识html5中video标签的熟悉 2.实现思路对 ...
- shell 示例1 从1叠加到100
从1叠加到100 echo $[$(echo +{..})] echo $[(+)*(/)] seq -s |bc
- EM算法原理详解
1.引言 以前我们讨论的概率模型都是只含观测变量(observable variable), 即这些变量都是可以观测出来的,那么给定数据,可以直接使用极大似然估计的方法或者贝叶斯估计的方法:但是当模型 ...
- 云计算--MPI
[root@localhost mpi]# mpicc -c base.c[root@localhost mpi]# mpicc -o base base.o[root@localhost mpi]# ...
- spring boot JPA中实体类常用注解
spring boot jpa中的注解很多,参数也比较多.没必要全部记住,但是经常查看官方文档也比较麻烦,记录一下一些常用的注解.通过一些具体的例子来帮助记忆. @Entity @Table(name ...
- Java 语言多态性
https://www.ibm.com/developerworks/cn/java/java-language-polymorphism/index.html 定义多态性 多态性是面向对象编程中的一 ...
- 在android 5.0以上,如何判断当前应用是在前台还是后台
今天在做项目时遇到这个问题,本来很简单的,但是在Android 5.1 的系统上运行却出错了,在网上查找答案后发现原来是在android 5.0 之后getRunningTask()方法被废弃,失效了 ...
- Ibatis.Net 动态SQL语句学习(六)
在学习动态SQL语句之前,首先必须对条件查询有一定了解,先来学习如何向IBatis.Net的映射文件里传入参数吧. 一.条件查询 1.传递单个参数 如根据Id查询: <select id=&qu ...
- C/C++的64位整型
在C/C++中,64为整型一直是一种没有确定规范的数据类型.现今主流的编译器中,对64为整型的支持也是标准不一,形态各异.一般来说,64位整型的定义方式有long long和__int64两种(VC还 ...