Luogu P5368 [PKUSC2018] 실제 랭킹

제목을 할 것입니다 SB 오래된 선수 (또한 오랜 시간 조정)

그것은 처음에 따라 분류 토론을 생각하기 쉽다 \ (내가 \) 개인은 카운트를 두 배로하지 않은

경우 \ (A_I이 \) , 분명히 경우 두 배가되지 않는다 \ ([0, \ lceil \ FRAC {A_I} {2} \ rceil) \) 번호를 \ ([A_I, \ infty) \) 번호 변환 시간은, 그 번호가 기억 될 수있다 (X 축 \) \ 상기에 기여 (\ C_x K ^) \을

경우 \ (A_I 것은 \) 두 배, 우리는 계산에있는 \ (I \) 순위, 표시 변경의 수의 \ (DLT \) . 이어서 \ ([A_I, 2a_i) \ ) 수보다 두배 사이 후 \ (2a_i \) , 표시 \ (X \) ,이 부분이되도록 \ (DLT C_x ^ {} \ ) .

이때, 다음 왼쪽 \ (K-1 DLT \ ) 동작 명백하게 \ (A_I \)의 두배 \ (2a_i \) 후, \ ([0, A_I) \)\ ([2a_i을 \ infty] \) 의 턴 두 숫자는 숫자가 표시된다 응답에 영향되지 아니된다 (Y를 \) \ 뿐만 아니라의 기여에 의해 \ (c_y ^ {K-1 ) \ -dlt}

번호를 논의 할 별도의 구체적인 실현 결국 위치의 값과 동일한

#include<cstdio>
#include<algorithm>
#define RI int
#define CI const int&
using namespace std;
const int N=100005,mod=998244353;
int n,k,a[N],rst[N],pfx[N],suf[N],id[N],ans[N],num,fact[N],inv[N];
inline void inc(int& x,CI y)
{
    if ((x+=y)>=mod) x-=mod;
}
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
    for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline void init(CI n)
{
    RI i; for (fact[0]=i=1;i<=n;++i) fact[i]=1LL*fact[i-1]*i%mod;
    for (inv[n]=quick_pow(fact[n]),i=n-1;~i;--i) inv[i]=1LL*inv[i+1]*(i+1)%mod;
}
inline int C(CI n,CI m)
{
    if (n<0||m<0) return 0; if (m==0) return 1; if (n<m) return 0;
    return 1LL*fact[n]*inv[m]%mod*inv[n-m]%mod;
}
inline int GB(CI x) //>=x
{
    return lower_bound(rst+1,rst+num+1,x)-rst;
}
inline int LB(CI x) //<=x
{
    return upper_bound(rst+1,rst+num+1,x)-rst-1;
}
int main()
{
    RI i; for (scanf("%d%d",&n,&k),i=1;i<=n;++i) scanf("%d",&a[i]),rst[i]=a[i];
    rst[n+2]=1e9+1; sort(rst+1,rst+n+3); num=unique(rst+1,rst+n+3)-rst-1;
    for (i=1;i<=n;++i) ++pfx[id[i]=GB(a[i])],++suf[id[i]];
    for (i=num-1;i;--i) suf[i]+=suf[i+1]; for (i=2;i<=num;++i) pfx[i]+=pfx[i-1];
    for (init(n),i=1;i<num;++i)
    {
        if (!rst[i]) { ans[i]=C(n,k); continue; }
        int ls=pfx[LB(rst[i]-1>>1)]; ans[i]=C(suf[i]-1+ls,k);
        int c=suf[GB(rst[i]<<1)],dlt=suf[i]-c-1,lt=pfx[LB(rst[i]-1)];
        inc(ans[i],1LL*C(pfx[LB((rst[i]<<1)-1)]-lt-1,dlt)*C(c+lt,k-dlt-1)%mod);
    }
    for (i=1;i<=n;++i) printf("%d\n",ans[id[i]]); return 0;
}

추천

출처www.cnblogs.com/cjjsb/p/12077911.html