zoukankan      html  css  js  c++  java
  • Luogu P5368 [PKUSC2018]真实排名

    老年选手只会做SB题了(还调了好久)

    很容易想到分类讨论,按第(i)个人有没有翻倍来算

    (a_i)未翻倍,显然此时将([0,lceil frac{a_i}{2} ceil))的数和([a_i,infty))的数翻倍都可以,记它们的个数为(x),则贡献为(C_x^k)

    (a_i)翻倍了,此时我们要算出(i)的排名变化了多少,记为(dlt)。然后在([a_i,2a_i))之间的数翻倍之后都是会超过(2a_i)的,记为(x),因此这部分就是(C_x^{dlt})

    然后此时还剩下(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
    ",ans[id[i]]); return 0;
    }
    
  • 相关阅读:
    Clean Code之JavaScript代码示例
    Okhttp3发送xml、json、文件的请求方法
    Ubuntu16.04 开机显示The system is running in low-graphics mode
    DELL R730服务器配置RAID及安装服务器系统 以及域的控制
    centos7搭建rsync
    centos7环境变量配错导致命令不能用
    centos7用lvm扩展xfs文件系统的根分区
    centos查看CPU的数量
    centos7无故重启-内核升级
    ubuntu scp命令或者用root连接ssh提示:Permission denied, please try again.错误
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12077911.html
Copyright © 2011-2022 走看看