• 数学【洛谷P4071】 [SDOI2016]排列计数


    P4071 [SDOI2016]排列计数

    求有多少种长度为 n 的序列 A,满足以下条件:

    1 ~ n 这 n 个数在序列中各出现了一次

    若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的

    满足条件的序列可能很多,序列数对 10^9+7 取模。

    错排+组合数。

    首先n-m个元素是完全错排,带公式即可。

    剩下的m个是要有序的,也就是从n个选m个。

    code:

    #include <iostream>
    #include <cstdio>
    
    #define int long long
    
    using namespace std;
    
    const int wx=1000007;
    
    const int mod=1e9+7;
    
    inline int read(){
    	int sum=0,f=1; char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    	while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
    	return sum*f;
    }
    
    int T,n,m;
    int d[wx],fac[wx],inv[wx];
    
    int ksm(int a,int b){
    	int re=1;
    	while(b){
    		if(b&1)re=re*a%mod;
    		a=a*a%mod;
    		b>>=1;
    	}
    	return re;
    }
    
    void pre(){
    	d[0]=1; d[1]=0; d[2]=1;
    	for(int i=3;i<=1000000;i++)d[i]=(((i-1)%mod)*((d[i-1]+d[i-2])%mod))%mod;
    	fac[0]=1;fac[1]=1;for(int i=2;i<=1000000;i++)fac[i]=i*fac[i-1]%mod;
    	inv[1000000]=ksm(fac[1000000],mod-2);
    	for(int i=1000000-1;i>=0;i--)
    		inv[i]=inv[i+1]*(i+1)%mod;
    }
    
    int CC(int x,int y){
    	if(x<y)return 0;
    	return (((fac[x]%mod*inv[y]%mod)%mod)*(inv[x-y]%mod))%mod;
    }
    
    int C(int x,int y){
    	return d[x-y]*(CC(x,y))%mod;
    }
    
    signed main(){
    	T=read(); pre();
    	while(T--){
    		n=read(); m=read();
    		printf("%lld
    ",C(n,m));
    	}
    	return 0;
    }
    
  • 相关阅读:
    组合索引
    常见的负载均衡策略
    jvm面试都有什么问题?
    Java常见面试题汇总-----------Java基础(NIO与IO的区别)
    关于OOM面试详解
    RabbitMQ几个常用面试题
    消息队列面试题及答案
    什么是B+树
    java并发编程 ||深入理解synchronized,锁的升级机制
    RabbitMQ中交换机的消息分发机制
  • 原文地址:https://www.cnblogs.com/wangxiaodai/p/9891214.html
Copyright © 2020-2023  润新知