CF938E Max History (Combinatorial Mathematics)

The original idea of ​​this topic, we first sort the sequence, and find that the contribution of each number is actually to find the number smaller than him and record it as cnt

Then enumerate the position of this number, then you can select j-1 from cnt to fill in the front, and then you need to arrange

But this exceeds the complexity, so we consider optimizing this combination number expression, the first is a simple reduction

After the appointment, we found that the subtraction of the number between the two factorials above and below is a constant. If this is the case, we can multiply the factorial of this constant outside, and then divide by the sum. Can turn the sum into a combined number

According to the change of Yang Hui triangle, it can become an answer that can be directly calculated

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const ll mod=1e9+7;
ll a[N];
ll qmi(ll a,ll b,ll mod){
    ll res=1;
    while(b){
        if(b&1)
        res=(res*a)%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res%mod;
}
int main(){
    ll n;
    cin>>n;
    ll tot=1;
    int i;
    for(i=1;i<=n;i++)
        tot=tot*i%mod;
    for(i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    sort(a+1,a+1+n);
    ll ans=0;
    int j;
    for(i=1;i<=n;i=j){
        for(j=i;a[j]==a[i];j++);
        if(j<=n)
            ans=(ans+tot*qmi(n-i+1,mod-2,mod)%mod*(j-i)%mod*a[i])%mod;
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/ctyakwf/p/12727592.html