1. 程式人生 > >BZOJ 4517--[Sdoi2016]排列計數

BZOJ 4517--[Sdoi2016]排列計數

ans ref algorithm 解決 ble con 接下來 stream href

4517: [Sdoi2016]排列計數

Time Limit: 60 Sec Memory Limit: 128 MB
Submit: 1727 Solved: 1067

Description

求有多少種長度為 n 的序列 A,滿足以下條件: 1 ~ n 這 n 個數在序列中各出現了一次 若第 i 個數 A[i] 的值為 i,則稱 i 是穩定的。序列恰好有 m 個數是穩定的 滿足條件的序列可能很多,序列數對 10^9+7 取模。

Input

第一行一個數 T,表示有 T 組數據。 接下來 T 行,每行兩個整數 n、m。 T=500000,n≤1000000,m≤1000000

Output

輸出 T 行,每行一個數,表示求出的序列數

Sample Input

5
1 0
1 1
5 2
100 50
10000 5000

Sample Output

0
1
20
578028887
60695423

題目鏈接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=4517

Solution

  顯然對於一次詢問,只要選定m個數放在原位,然後使其他數字都不放在原位即可。。

  設f [ i ]表示長度為i的每一位a [ i ] ! = i的方案數。。

  於是答案顯然就是C(n,m) * f [ n-m ]。。。

  組合數可以用乘法逆元解決。。

  考慮怎麽處理f [ i ]。。首先打表可知f [ i ]一定是(i-1)的倍數。。。

  f[1]=0

  f[2]=1  f[2]/1=1

  f[3]=2  f[3]/2=1

  f[4]=9  f[4]/3=3

  f[5]=44  f[5]/4=11

  f[6]=265 f[6]/5=53

  顯然可以發現 f [ i ] / ( i - 1 ) = f [ i - 1 ] + f [ i - 2 ]

  於是 f [ i ] = ( f [ i - 1 ] + f [ i - 2 ] ) * ( i - 1 )

  O(n)遞推,O(1)詢問。。

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#define pa pair<LL,LL>
#define LL long long
using namespace std;
inline LL read(){
    LL x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
inline void Out(LL a){
    if(a>9) Out(a/10);
    putchar(a%10+‘0‘);
}
const LL inf=1e9+10;
const LL mod=1e9+7;
const int N=1000050;
LL n,m;
LL f[N+50],jc[N+50],ny[N+50];
LL C(LL x,LL y){
	return jc[y]*ny[x]%mod*ny[y-x]%mod;
}
int main(){
	f[0]=1;f[1]=0;
	jc[0]=jc[1]=ny[0]=ny[1]=1;
	for(LL i=2;i<=N;++i){
		f[i]=(f[i-1]+f[i-2])%mod*(i-1)%mod;
		ny[i]=(mod-mod/i)*ny[mod%i]%mod;
	}
	for(LL i=2;i<=N;++i){
		ny[i]=ny[i-1]*ny[i]%mod;
		jc[i]=jc[i-1]*i%mod;
	}
	int T;scanf("%d",&T);
	LL ans;
	while(T--){
		n=read();m=read();
		ans=C(m,n)*f[n-m]%mod;
		Out(ans);puts("");
	}
	return 0;
}

  

  

This passage is made by Iscream-2001.

BZOJ 4517--[Sdoi2016]排列計數