码迷,mamicode.com
首页 > 其他好文 > 详细

【Pkusc2018】真实排名

时间:2019-01-17 21:24:02      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:put   考试   using   mat   name   code   比赛   pow   道具   

Description

小C是某知名比赛的组织者,该比赛一共有\(n\)名选手参加,每个选手的成绩是一个非负整数,定义一个选手的排名是:成绩不小于他的选手的数量(包括他自己)。例如如果\(3\)位选手的成绩分别是\([1,2,2]\),那么他们的排名分别是\([3,2,2]\)

拥有上帝视角的你知道所有选手的实力,所以在考试前就精准地估计了每个人的成绩,设你估计的第\(i\)个选手的成绩为\(A_i\),且由于你是上帝视角,所以如果不发生任何意外的话,你估计的成绩就是选手的最终成绩。

但是在比赛当天发生了不可抗的事故(例如遭受到了外星人的攻击),导致有一些选手的成绩变成了最终成绩的两倍,即便是有上帝视角的你也不知道具体是哪些选手的成绩翻倍了,唯一知道的信息是这样的选手恰好有\(k\)个。

现在你需要计算,经过了不可抗事故后,对于第\(i\)位选手,有多少种情况满足他的排名没有改变。

由于答案可能过大,所以你只需要输出答案对998244353取模的值即可。

Input

第一行两个正整数\(n,k\)

第二行\(n\)个非负整数\(A_1..A_n\)

\(1 \leq k < n \leq 10^5 ,0 \leq Ai \leq 10^9\)

Output

输出\(n\)行,第i行一个非负整数\(ans_i\),表示经过不可抗事故后,第\(i\)位选手的排名没有发生改变的情况数。

Solution

据说是去年的签到题啊。。

对于每一个\(a_i\),把\(n\)个数划分成4类

  • \(\{a_j \mid a_j < \frac{a_i+1}{2} \}\)

  • \(\{a_j \mid \frac{a_i+1}{2} \leq a_j < a_i \}\)

  • \(\{a_j \mid a_j \leq a_j < a_i*2 , j \neq i \}\)

  • \(\{a_j \mid a_i*2 \leq a_j \}\)

易发现第一类和第四类无论如何都不会对\(a_i\)的排名产生影响

考虑$ a_i $要不要翻倍。

\(a_i\)翻倍,则第三类数也同时要翻倍,不然会影响\(a_i\)的排名

但是翻倍后,一,二,四这几类数是否翻倍就不会对\(a_i\)的排名产生影响

\(a_i\)不翻倍,那么\(k\)个翻倍的数只能存在于一,四类中

组合数算一下就好了

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int Mod=998244353;
int n,k,a[100010],b[100010],J[100010],G[100010];
int fpow(int a,int k)
{
    int ans=1;
    while (k)
    {
        if (k&1) ans=1LL*ans*a%Mod;
        a=1LL*a*a%Mod;
        k>>=1;
    }
    return ans;
}
int C(int n,int k)
{
    if (n<k) return 0;      
    return 1LL*J[n]*G[k]%Mod*G[n-k]%Mod; 
}
int main()
{
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
    sort(b+1,b+n+1);
    b[n+1]=2000000000;
    J[0]=1;
    for (int i=1;i<=n;i++) J[i]=1LL*J[i-1]*i%Mod;
    for (int i=0;i<=n;i++) G[i]=fpow(J[i],Mod-2);
    for (int i=1;i<=n;i++)
    {
        if (a[i]==0)
        {
            printf("%d\n",C(n,k));
            continue;
        }//a[i]=0的时候特判
        int x1=lower_bound(b+1,b+n+1,(a[i]+1)/2)-b-1;//第一类数
        int x2=lower_bound(b+1,b+n+1,a[i])-b-1-x1;//第二类数
        int x3=lower_bound(b+1,b+n+1,a[i]*2)-b-1-x1-x2;x3--;//第三类数
        int x4=n-x1-x2-x3;x4--;//第四类数
        int ans=0;
        if (k-x3-1>=0) ans+=C(x1+x2+x4,k-x3-1); //a[i]翻倍
        ans+=C(x1+x3+x4,k);ans%=Mod;//a[i]不翻倍
        printf("%d\n",ans);
    }
    return 0;
}

【Pkusc2018】真实排名

标签:put   考试   using   mat   name   code   比赛   pow   道具   

原文地址:https://www.cnblogs.com/Code-Geass/p/10284296.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!