CF938E-组合数

link:https://codeforces.com/contest/938/problem/E
题意:给一个序列 a ,按如下方式计算 fa

  • 初始 fa=0,M=1
  • 对每个 2in,如果 aM<aifafa+aM,然后 M=i
    对所有 a 的排列计算 fa 并其在模 109+7 下的和。
    1n106,1ai109

对每个序列的 fa 的值是一段从 a1 开始的上升序列的和,并且 a 的最大值没有贡献,反过来考虑每个 ai<max(a) 的贡献:

  • ai 在位置 j 处出现,要产生贡献当且仅当前面的数严格比 ai 小,假设这样的数有 si 个,则有 si!/(si(j1))! 种放法,后面的数随便放,有 (nj)! 种,j=1nsi!(nj)!(sij+1)!=si!j=1n(nj)!(sij+1)!(n1si)!(n1si)!=si!(n1si)!j=1n(njn1si)经典上指标求和,翻转指标,从(nk)=(n1k)+(n1k1)(n1)=0,为 可以倒推:si!(n1si)!j=0n1(jn1si)=si!(n1si)!(nnsi)
  • 对每个值计算贡献即可
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
const int N=1e6+55;
const int MOD=1e9+7;
int ksm(int a,int b){
int ret=1;a%=MOD;
for(;b;b>>=1,a=(ll)a*a%MOD)if(b&1)ret=(ll)ret*a%MOD;
return ret;
}
int n,a[N],fact[N],inv_fact[N];
map<int,int> S;
int C(int n,int k){
if(k>n)return 0;
return (ll)fact[n]*inv_fact[k]%MOD*inv_fact[n-k]%MOD;
}
int main(){
fastio;
fact[0]=1;
rep(i,1,N-5)fact[i]=(ll)fact[i-1]*i%MOD;
inv_fact[N-5]=ksm(fact[N-5],MOD-2);
for(int i=N-5;i>=1;i--)inv_fact[i-1]=(ll)inv_fact[i]*i%MOD;
cin>>n;
int mx=0;
rep(i,1,n){
cin>>a[i];
S[a[i]]++;
mx=max(mx,a[i]);
}
int cnt=0,ans=0;
for(auto [x,c]:S)if(x!=mx){
ans=(ans+(ll)x*fact[cnt]%MOD*fact[n-cnt-1]%MOD*C(n,n-cnt)%MOD*c%MOD)%MOD;
cnt+=c;
}
cout<<ans;
return 0;
}
posted @   yoshinow2001  阅读(16)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2021-03-21 [比赛记录]2020-2021 Summer Petrozavodsk Camp, Day 6: Korean Contest
点击右上角即可分享
微信分享提示