题意:
给n,m,(2e5>=n>=m)n代表时长度为n的数组,构造一个长度为n,值的范围1~m的数组,满足下面条件
1.数组中只能且必须出现一对相同的数字
2.先递增再递减
题解:
数组n中有n-1种值,从m中选n-1个值,c(m,n-1)
除了最大的那个元素,剩下n-2个有一个要重复,c(n-2,1)=n-2
除了最大的那个元素以及两个重复的元素,剩下n-3个元素,每个元素都有两种选择,在最大值左侧或者最大值右侧,2^(n-3)
ans=c(m,n-1)*(n-2)*2^(n-3),由于m和n很大,用递推算组合数会超时,因此直接用阶乘的公式就可以了。
代码:
#include<bits/stdc++.h> #define endl '\n' using namespace std; typedef long long ll; typedef double db; typedef pair<int,int> pii; typedef vector<int> vi; #define check system("pause") #define all(x) (x).begin(),(x).end() #define de(a) cout<<#a<<" = "<<a<<endl #define dd(a) cout<<#a<<" = "<<a<<" " #define mp make_pair #define pb push_back #define fi first #define se second #define lowbit(a) ((a)&-(a)) #define INF 0x3f3f3f3f const ll mod = 998244353; const int N = 2e5+20; #define dep(i,a,b) for(int i=(a);i>=(b);i--) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define mes(p,b) memset(p,b,sizeof(p)) #define sz(x) int(x.size()) ll qk(int x,int y){ ll ans=1,res=x; for(;y;y>>=1,res*=res,res%=mod){ if(y&1) ans*=res,ans%=mod; }return ans; } ll f[N]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n,m; cin>>n>>m; if(n==2){ cout<<0;return 0; } ll ans=qk(2,n-3); ans=ans*(n-2)%mod; f[1]=1; rep(i,2,m) f[i]=f[i-1]*i%mod; ans=ans*f[m]%mod; ans=ans*qk(f[m-n+1],mod-2)%mod; ans=ans*qk(f[n-1],mod-2)%mod; cout<<ans; return 0; }