题目链接

错位排列\(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]排列计数(错位排列 逆元)的更多相关文章

  1. [BZOJ4517][SDOI2016]排列计数(错位排列)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1616  Solved: 985[Submit][Statu ...

  2. BZOJ 4517: [Sdoi2016]排列计数 错排+逆元

    4517: [Sdoi2016]排列计数 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i, ...

  3. BZOJ 4517: [Sdoi2016]排列计数 [容斥原理]

    4517: [Sdoi2016]排列计数 题意:多组询问,n的全排列中恰好m个不是错排的有多少个 容斥原理强行推♂倒她 $恰好m个不是错排 $ \[ =\ \ge m个不是错排 - \ge m+1个不 ...

  4. BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 911  Solved: 566[Submit][Status ...

  5. 数学(错排):BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 434[Submit][Status ...

  6. BZOJ 4517: [Sdoi2016]排列计数 错排公式

    4517: [Sdoi2016]排列计数 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4517 Description 求有多少种长度为 ...

  7. Bzoj 4517: [Sdoi2016]排列计数(排列组合)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MB Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ...

  8. BZOJ 4517: [Sdoi2016]排列计数(组合数学)

    题面 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m ...

  9. BZOJ 4517--[Sdoi2016]排列计数(乘法逆元)

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1727  Solved: 1067 Description ...

随机推荐

  1. html5 canvas贝塞尔曲线篇(上)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 控制台console对象常用的一些方法

    console.log():调试中最常用的方法,用于在控制台窗口显示信息. console.log(123); console.warn():输出信息时,在最前面加一个黄色三角,表示警告 consol ...

  3. IOS 与 PHP 通信加密,使用AES 128 CBC no padding

    这个网上的资料真实浩如烟海,但是真正有价值的屈指可数 自己尝试了一天多,终于还是搞定了. 再次要感谢网上的前辈么. 比如下面这个关于php和java端的实现: http://my.oschina.ne ...

  4. expect 交互 模拟ssh 登陆

    模拟ssh登录 #!/bin/bash Ip='192.168.1.6' # 循环就行 RemoteUser='user' # 普通用户 RemotePasswd='userpasswd' # 普通用 ...

  5. 批量增加Linux系统账号、重置账号密码、FTP账号批量测试

    批量增加Linux系统账号.重置账号密码是用Linux Shell脚本来做的:批量FTP账号测试是用Python脚本来做的.这些脚本都是读取一个用户名和密码文件,然后基于该用户名密码文件进行自动批量测 ...

  6. CSS background汇总

    本文更新版本 ,请跳转 所有背景属性都不能继承. 1.    background-color 所有元素都能设置背景颜色. background-color的默认值是transparent:也就是说, ...

  7. yui压缩JS和CSS文件

    CSS和JS文件经常需要压缩,比如我们看到的XX.min.js是经过压缩的JS. 压缩文件第一个是可以减小文件大小,第二个是对于JS文件,默认会去掉所有的注释,而且会去掉所有的分号,也会将我们的一些参 ...

  8. Servlet笔记8--乱码解决方案

    乱码解决方案: 代码详解: package com.bjpowernode.javaweb.servlet; import java.io.IOException; import javax.serv ...

  9. How to become a successful bug bounty hunter

    出处:https://www.hackerone.com/blog/become-a-successful-bug-bounty-hunter 如果你梦想成为赏金猎人,你的梦想就会成真 - 不要把你的 ...

  10. mysql主键的缺少导致备库hang

    最近线上频繁的出现slave延时的情况,经排查发现为用户在删除数据的时候,由于表主键的主键的缺少,同时删除条件没有索引,或或者删除的条件过滤性极差,导致slave出现hang住,严重的影响了生产环境的 ...