zoukankan      html  css  js  c++  java
  • 【PKUSC2018】真实排名

    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 eq 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
    ",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
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    网络通信之 字节序转换原理与网络字节序、大端和小端模式
    [C/C++]大小端字节序转换程序
    面向对象和面向过程的区别
    编译libjpeg
    地形系统lod
    c/c++ 代码中使用sse指令集加速
    个人作品- 蘑菇大战
    个人作品- 几何战争
    Obj格式模型 读取
    各大引擎矩阵的矩阵存储方式 ----行矩阵 or 列矩阵
  • 原文地址:https://www.cnblogs.com/Code-Geass/p/10284296.html
Copyright © 2011-2022 走看看