[LOJ 6432] [PKUSC 2018] real rankings

[LOJ 6432] [PKUSC 2018] real rankings

The meaning of problems

Given \ (n \) a competitor's scores, select one of the \ (k \) a double makes their achievement. For each contestant has to answer how many kinds of programs makes his ranking does not change.

\ (N \ 10 ^ 5 \)

answer

A unique court out of the question?

We discuss two types, one is to double the current players, one is not doubled.

  • If the current players are not doubled, so more than doubling the current players after all the players can not be doubled, others are free. Number of program is obviously in the rest of the people selected \ (k \) the number of months of the program.
  • If the current player is doubled, then doubled after all players must be more than doubled, others are free. Program number is also a number of combinations.

So the question on sand sculpture done. I can really only field A sand sculpture of this problem.

Reference Code

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

Guess you like

Origin www.cnblogs.com/rvalue/p/10934967.html