[LOJ 6432] [2018 PKUSC] 실제 랭킹

[LOJ 6432] [2018 PKUSC] 실제 랭킹

문제의 의미

주어 (N \) \ 경쟁사의 점수는 중 하나를 선택합니다 \ (케이 \)를 이중 자신의 성취를한다. 각 참가자는 프로그램의 많은 종류의 자신의 순위가 변경되지 않습니다 만드는 방법에 답이 들어.

\ (N \ 10 ^ 5 \)

문제 해결

질문 중 독특한 법원?

우리는 두 가지 유형을 논의, 하나는 현재의 선수를 두 배로하는 것입니다, 하나는 두 배가되지 않습니다.

  • 현재 플레이어가 두 배가되지 않으면, 그래서 더 모든 선수가 두 배가 될 수 없다 후 현재 플레이어를 두 배로보다, 다른 사람은 무료입니다. 프로그램의 수는 선택된 사람들의 나머지 부분에서 분명히 \ (케이 \) 프로그램의 개월 수.
  • 현재 플레이어가 두 배가되면, 두 배 이상이어야합니다 모든 선수 이후 두 배로, 다른 사람은 무료. 프로그램 번호는 조합의 숫자입니다.

이렇게 모래 조각에 대한 질문. 난 정말에만이 문제의 모래 조각을 필드 수 있습니다.

참조 코드

#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;
}

추천

출처www.cnblogs.com/rvalue/p/10934967.html