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 ...
随机推荐
- [Apio2012]dispatching 左偏树做法
http://codevs.cn/problem/1763/ 维护子树大根堆,当子树薪水和>m时,删除最贵的点 #include<cstdio> #include<iostre ...
- CF989C A Mist of Florescence (构造)
CF989C A Mist of Florescence solution: 作为一道构造题,这题确实十分符合构造的一些通性----(我们需要找到一些规律,然后无脑循环).个人认为这题规律很巧妙也很典 ...
- Python 入门基础9 --函数基础2 实参与形参
今日内容: 一.函数参数 1.形参与实参定义 2.实参分类 3.形参分类 4.可变参数的整体使用 一.形参与实参定义 def fn(参数们): pass 1.1 形参 定义函数,在括号内声明的变量名, ...
- linux backtrace()详细使用说明,分析Segmentation fault【转】
转自:http://velep.com/archives/1032.html 在此之前,开发eCos应用程序时,经常碰到程序挂掉后,串口打印输出一大串让人看不懂的数据.今天才明白,原来这些数据是程序挂 ...
- mac 安装gevent报错
运行pip install gevent报错 错误信息如下 xcrun: error: invalid active developer path (/Library/Developer/Comman ...
- 搜索引擎ElasticSearchV5.4.2系列一之ES介绍
相关博文: 搜索引擎ElasticSearchV5.4.2系列一之ES介绍 搜索引擎ElasticSearchV5.4.2系列二之ElasticSearchV5.4.2+kibanaV5.4.2+x- ...
- js async await 终极异步解决方案
既然有了promise 为什么还要有async await ? 当然是promise 也不是完美的异步解决方案,而 async await 的写法看起来更加简单且容易理解. 回顾 Promise Pr ...
- Nginx安装方式探究
Ubuntu 16.04(阿里云ECS),Nginx 1.10.3 (Ubuntu) 本文探究两种安装方式: 1.源码安装(手动) 2.APT安装(自动) 源码安装(手动) 步骤简介: 下载.解压.. ...
- Python黑魔法
1. 赋值 In [1]: x = 1 ...: y = 21 ...: print x, y ...: ...: x, y = y, x ...: print x, y 1 21 21 1 2. 列 ...
- 关于vim复制剪贴粘贴命令的总结
最近在使用vim,感觉很好很强大,但是在使用复制剪切粘贴命令是,碰到了一些小困惑,网上找了一些资料感觉很不全,讲的也不好,遂自己进行实践并总结了. 首先是剪切(删除): 剪切其实也就顺带删除了所选择的 ...