cpdefprce education round 83 D. Count the Arrays

题意:

给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;
}
原文地址:https://www.cnblogs.com/FZUlh/p/12455268.html