CF938E Max History(組み合わせ数学)

このトピックの元のアイデアは、最初にシーケンスを並べ替え、各数値の寄与が実際には彼より小さい数値を見つけてcntとして記録することであることがわかりました

次に、この番号の位置を列挙します。次に、cntからj-1を選択して前を埋めることができます。次に、配置する必要があります。

しかし、これは複雑さを超えているため、この組み合わせの数値式を最適化することを検討します。最初の方法は単純な削減です

予約後に、上下2つの階乗の間の数の減算が定数であることがわかりました。これが当てはまる場合は、この定数の階乗を乗算し、合計で除算できます。合計を合計数に変えることができます

ヤンフイ三角形の変化に合わせて、直接計算できる答えになる

#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 ; 
    }
     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 + 1mod- 2、mod)%mod *(ji)%mod * a [i])%mod; 
    } 
    cout << ans << endl;
    0を返し ます
}
コードを表示

 

おすすめ

転載: www.cnblogs.com/ctyakwf/p/12727592.html