Educational Codeforces Round 83 (Rated for Div. 2)D(排列组合)

 1 #define HAVE_STRUCT_TIMESPEC
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 const long long mod = 998244353;
 5 long long jiechen[400007],niyuan[400007];
 6 long long qpow(long long a,long long b){
 7     if(b<0)
 8         return 0;
 9     long long res=1;
10     a%=mod;
11     while(b){
12         if(b&1)
13             res=(res*a)%mod;
14         b>>=1;
15         a=(a*a)%mod;
16     }
17     return res;
18 }
19 long long inv(long long x){
20     return qpow(x,mod-2);
21 }
22 long long calc(long long x,long long y){
23     return x<y?0:jiechen[x]*niyuan[y]%mod*niyuan[x-y]%mod;
24 }
25 int main(){
26     ios::sync_with_stdio(false);
27     cin.tie(NULL);
28     cout.tie(NULL);
29     long long n,m;
30     cin>>n>>m;
31     if(n==2){
32         cout<<0;
33         return 0;
34     }
35     jiechen[0]=1ll;
36     for(long long i=1;i<=n+m;++i)
37         jiechen[i]=(i*jiechen[i-1])%mod;
38     niyuan[n+m]=qpow(jiechen[n+m],mod-2);
39     for(long long i=n+m-1;i>=0;--i)
40         niyuan[i]=((i+1)*niyuan[i+1])%mod;
41     long long temp=0;
42     for(long long i=2;i<n;++i){
43         long long z=calc(n-3,i-2);//temp为n-3个数的全排列+1,即n个数去掉两个相同的数和一个最大值作为峰,剩余n-3个数自由组合排放在峰左右两侧的方案个数
44         temp=(temp+z)%mod;
45     }
46     long long ans=0;
47     for(long long i=1;i<=m;++i){
48         long long now=(n-2)*calc(i-1,n-2)%mod;//now为从当前i个数里除了一对相同值以外i-1个数中选n-2个数并且这对相同值除了最大值都可以所以有n-2种选择
49         ans=(ans+(temp*now%mod))%mod;//挑选数字的大小和排列组合的乘积加到答案中
50     }
51     cout<<ans;
52     return 0;
53 }

猜你喜欢

转载自www.cnblogs.com/ldudxy/p/12460248.html