题目链接

错位排列\(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. Spark记录-spark-submit学习

    #查看帮助:./bin/spark-submit --help   ./bin/spark-shell --help 用法1: spark-submit [options] <app jar | ...

  2. oracle connect by用法篇 (转)

    1.基本语法 select * from table [start with condition1] connect by [prior] id=parentid 1 2 1 2 一般用来查找存在父子 ...

  3. Lua程序设计(三)面向对象实现一个简单的类

    1.Lua面向对象实现步骤 ①创建一个全局表(称之为元表) ②设置这个元表的__index值(值通常为元表自己,这样就能通过__index查找到对应的属性和方法)__index 赋值其实是一个func ...

  4. LINQ 查询

    概述 事实上,对于LINQ to Objects来说,就是通过为IEnumerable<T>接口定义了一组约50个扩展方式来实现的. Lambda表达式(拉姆达表达式,Lambda Exp ...

  5. Asp.net操作Word文档,原来这么简单啊!

    引用Word对象库文件  具体做法是打开菜单栏中的项目>添加引用>浏览,在打开的“选择组件”对话框中找到MSWORD.OLB后按确定即可引入此对象库文件,vs.net将会自动将库文件转化为 ...

  6. 20155206 2016-2017-2 《Java程序设计》第7周学习总结

    20155206 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 认识时间与日期 1.格林威治时间(GMT):通过观察太阳而得,因为地球公转轨道为椭圆形且速度 ...

  7. flask_sqlalchemy的使用

    第一配置文件 # coding:utf-8 DIALECT = 'mysql' DRIVER = 'pymysql' USERNAME = 'root' PASSWORD = ' HOST = '12 ...

  8. Visual Studio 配置 Avalon 自动补全

    以VS2013为例: 1.关闭 Visual Studio 2.打开 C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Packa ...

  9. 【Python】测试dpkt解析pcap

    1.前言 本想借助dpkt解析mail.dns.http来辅助分析pcap包进行分析,查阅资料学习却发现并不如使用scapy那么方便. dpkt是一个python模块,可以对简单的数据包创建/解析,以 ...

  10. pip 18.1: pipenv graph results in ImportError: cannot import name 'get_installed_distributions'

    I'm currently using python3 -m pip install pip==10.0.1python3 -m pip install pipenv==2018.5.18 Once ...