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 ...
随机推荐
- Java基础-标识符与关键字
Java基础-标识符与关键字 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是标识符 标识符就是程序员在编写程序时,给类,变量,方法等起的名字. 二.标识符的命名规则 1& ...
- 如何修改Linux的TTL值
原文地址:http://www.linuxidc.com/Linux/2011-11/47701.htm 网络黑客如果用ping命令去探测 一个主机,根据TTL基数可以推测操作系统的类型.对于一个没 ...
- spring注解 @Scheduled(cron = "0 0 1 * * *")实现定时的执行任务
@Scheduled(cron = "0 0 1 * * *") 在使用该注解以前请做好以下准备工作,配置好相应的xm文件. 配置定时注解的步骤:http://blog.csdn. ...
- bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机
http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...
- CMSZU站群管理系统 升级到 v1.8 [源码下载]
CmsZu 简介 CMSZU即CMS族,是个网站内容管理平台,基于PHP+MYSQL技术创建,源码开放. CmsZu 更新说明 V1.8 修改了些bug 完善数据库管理 -> 数据库表管理的 字 ...
- 【工具】用命令行与Python使用YARA规则
1.前言 YARA是一款旨在帮助恶意软件研究人员识别和分类恶意软件样本的开源工具,使用YARA可以基于文本或二进制模式创建恶意软件家族描述与匹配信息.现在已经被多家公司所运用于自身的产品. 2.YAR ...
- Submatrix Sum
Given an integer matrix, find a submatrix where the sum of numbers is zero. Your code should return ...
- 谁在call我-backtrace的实现原理【转】
转自:http://www.xuebuyuan.com/1504689.html 显示函数调用关系(backtrace/callstack)是调试器必备的功能之一,比如在gdb里,用bt命令就可以查看 ...
- shell函数中eof报错(warning: here-document at line 9 delimited by end-of-file (wanted `EOF'))
在shell编写函数时,函数中有eof和EOF,如果是在sublime编写按照格式tab缩进会有以下报错 解决办法: 取消函数中的tab缩进,在运行即可
- 关于iTerm2中颜色配置及快捷键使用技巧(亲测)
https://github.com/mbadolato/iTerm2-Color-Schemes http://chriskempson.com/projects/base16 (同事用的) 按照g ...