题目描述
七夕已经到了!牛郎织女迫切想要见面,但我们都知道他们要想跨越银河就需要构造鹊桥。
现在,天上飞了无数只喜鹊并且飞行高度 h (1≤h≤m )h\ (1 \leq h \leq m\ )h (1≤h≤m ),他们都想尽快帮助牛郎织女见面。
鹊桥的形状是一个倒 VVV,倒 VVV 指的是 存在 x∈(1,n)x \in (1,n)x∈(1,n) 使得 ai−1<ai ( i∈(1,x] )a_{i-1} <a_i\ (\ i \in (1,x]\ )ai−1<ai ( i∈(1,x] ) 且 ai>ai+1 ( i∈[x,n) )a_i>a_{i+1}\ (\ i \in [x, n)\ )ai>ai+1 ( i∈[x,n) ) 。
即对于最大值所在的位置,在这个位置左边的所有数字严格递减,在这个位置右边的所有数字严格递减。
但若想鹊桥稳固则必须有且仅有两个位置的喜鹊飞行高度一样。
牛郎织女想请你帮忙计算一下有多少种稳固的鹊桥,以便于他们见面没有安全隐患。
例:1 3 6 9 7 6 4 21\ 3\ 6\ 9\ 7\ 6\ 4\ 21 3 6 9 7 6 4 2 即为一个稳固的鹊桥。
答案可能很大,请你输出答案对 109+710^9+7109+7 取模后的结果。
输入描述:
输入一行两个正整数 n,m ( 3≤n≤m≤106 )n,m\ (\ 3 \leq n \leq m \leq 10^6\ )n,m ( 3≤n≤m≤106 )
输出描述:
输出一行一个结果,由于答案过大请对 109+710^9+7109+7 取模。
示例1
输入
复制3 4
3 4
输出
复制6
6
说明
对于样例 共有如下 666 种稳固的鹊桥 1 4 11\ 4\ 11 4 1 1 3 11\ 3\ 11 3 1 1 2 11\ 2\ 11 2 1 2 3 22\ 3\ 22 3 2 2 4 22\ 4\ 22 4 2 3 4 33\ 4\ 33 4 3
做法
我们先从m个高度中选n-1个不同的高度(有两个数要求相同,所以选n-1个不同的数即可),就是组合数C[m][n-1]。然后最大的那个数做桥的顶端,不用管。剩下的n-2个数都可以拿来做那两个相同的数,因此再乘以(n-2)。剩下的n-3个数,每个数都能放在桥的左右两侧,因此再乘以2的n-3次方
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long jc[1000010],ny[1000010];
const long long mod=1e9+7;
long long ksm(long long a,long long b){
long long ans=1;
while(b){
if(b%2) ans=ans*a%mod;
b/=2;
a=a*a%mod;
}
return ans;
}
int main(){
jc[0]=1;
for(int i=1;i<=1000000;i++) jc[i]=1ll*jc[i-1]*i%mod;
ny[1000000]=ksm(jc[1000000],mod-2);
for(int i=1000000-1;i>=0;i--) ny[i]=ny[i+1]*1ll*(i+1)%mod;
scanf("%d%d",&n,&m);
if(n>m){//不足以搭成桥
cout<<0;
return 0;
}
cout<<1ll*jc[m]*ny[n-1]%mod*ny[m-n+1]%mod*n-2%mod*ksm(2,n-3)%mod;
}
我当时写的时候没想到,一直在想,桥的每个位置(共有n个位置)有多少个不同的数能放。其实换个方向考虑就行,n-1个数能放哪些位置