給定 \(n\) 個選手的成績, 選中其中 \(k\) 個使他們的成績翻倍. 對於每一個選手回答有多少種方案使得他的排名不發生變化.c++
\(n\le 10^5\)git
場上惟一A掉的題?spa
分兩類討論, 一類是當前選手翻倍了, 一類是不加倍.code
因而這沙雕題就作完了. 場上只A這一題的我可真是個沙雕.blog
#include <bits/stdc++.h> const int MAXN=1e5+10; const int MOD=998244353; int n; int k; int a[MAXN]; int s[MAXN]; int h[MAXN]; int d[MAXN]; int inv[MAXN]; int fact[MAXN]; int ReadInt(); int C(int,int); int Pow(int,int,int); int main(){ n=ReadInt(); k=ReadInt(); for(int i=1;i<=n;i++) s[i]=a[i]=ReadInt(); std::sort(s+1,s+n+1); fact[0]=1; for(int i=1;i<=n;i++) fact[i]=1ll*fact[i-1]*i%MOD; inv[n]=Pow(fact[n],MOD-2,MOD); for(int i=n;i>=1;i--) inv[i-1]=1ll*inv[i]*i%MOD; for(int i=1;i<=n;i++){ if(a[i]==0) printf("%d\n",C(n,k)); else{ int ans=0; int d=std::lower_bound(s+1,s+n+1,a[i])-std::lower_bound(s+1,s+n+1,(a[i]+1)/2); (ans+=C(n-d-1,k))%=MOD; d=std::lower_bound(s+1,s+n+1,a[i]*2)-std::lower_bound(s+1,s+n+1,a[i]); (ans+=C(n-d,k-d))%=MOD; printf("%d\n",ans); } } return 0; } int C(int n,int m){ return n<m||n<0||m<0?0:1ll*fact[n]*inv[m]%MOD*inv[n-m]%MOD; } int Pow(int a,int n,int p){ int ans=1; while(n>0){ if(n&1) ans=1ll*a*ans%p; a=1ll*a*a%p; n>>=1; } return ans; } inline int ReadInt(){ int x=0; register char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)){ x=x*10+ch-'0'; ch=getchar(); } return x; }