• [CC-PERMUTE]Just Some Permutations 3


    [CC-PERMUTE]Just Some Permutations 3

    题目大意:

    (T(Tle10^5))次询问,每次询问有多少长度为(n(nle10^6))的排列,满足任意相邻两个数的和不超过(m)

    思路:

    找规律。

    首先打表出来是这样的:

    1:   1
    2:   0    0    2
    3:   0    0    0    2    6
    4:   0    0    0    0    4   12   24
    5:   0    0    0    0    0    4   36   72  120
    6:   0    0    0    0    0    0    8   72  288  480  720
    7:   0    0    0    0    0    0    0    8  216  864 2400 3600 5040
    8:   0    0    0    0    0    0    0    0   16  432 3456 9600 21600 30240 40320
    9:   0    0    0    0    0    0    0    0    0   16 1296 10368 48000 108000 211680 282240 362880
    10:   0    0    0    0    0    0    0    0    0    0   32 2592 41472 192000 648000 1270080 2257920 2903040 3628800
    

    把左边的(0)去掉,就是:

    2:0   2
    3:0   2    6
    4:0   4   12   24
    5:0   4   36   72  120
    6:0   8   72  288  480  720
    7:0   8  216  864 2400 3600 5040
    8:0  16  432 3456 9600 21600 30240 40320
    9:0  16 1296 10368 48000 108000 211680 282240 362880
    10:0  32 2592 41472 192000 648000 1270080 2257920 2903040 3628800
    

    发现最上面一层斜线就是阶乘,往下就是不停乘(m,m-1)

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    typedef long long int64;
    const int N=1e6+1,mod=1e9+7;
    int p[N],fac[N];
    inline int power(int a,int k) {
    	int ret=1;
    	for(;k;k>>=1) {
    		if(k&1) ret=(int64)ret*a%mod;
    		a=(int64)a*a%mod;
    	}
    	return ret;
    }
    int main() {
    	for(register int i=fac[0]=1;i<N;i++) {
    		fac[i]=(int64)fac[i-1]*i%mod;
    	}
    	for(register int T=getint();T;T--) {
    		int n=getint(),m=getint();
    		if(n==1) {
    			puts("1");
    			continue;
    		}
    		if(m>=n*2-1) {
    			printf("%d
    ",fac[n]);
    			continue;
    		}
    		if(m<n+1) {
    			puts("0");
    			continue;
    		}
    		m-=n-1;
    		n-=m;
    		int ans=fac[m];
    		ans=(int64)ans*power((int64)m*(m-1)%mod,n/2)%mod;
    		if(n&1) ans=(int64)ans*(m-1)%mod;
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    刷题-力扣-223. 矩形面积
    刷题-力扣-135. 分发糖果
    刷题-力扣-134. 加油站
    刷题-力扣-343. 整数拆分
    刷题-力扣-162. 寻找峰值
    刷题-力扣-371. 两整数之和
    20191114-2 Beta事后诸葛亮会议
    Beta阶段贡献分配
    扛把子组20191114-4 Beta发布用户使用报告
    beta 2/2 阶段中间产物提交
  • 原文地址:https://www.cnblogs.com/skylee03/p/9811692.html
Copyright © 2020-2023  润新知