zoukankan      html  css  js  c++  java
  • Jzoj5414 幸运值

    校庆志愿者小Z在休息时间和同学们玩卡牌游戏。一共有n张卡牌,每张卡牌上有一个数Ai,每次可以从中选出k张卡牌。一种选取方案的幸运值为这k张卡牌上数的异或和。小Z想知道所有选取方案的幸运值之和除以998244353的余数。

    为什么中间跳过了几道题?因为现在来不及改了先把过了的搬上来吧

    套路:按位计算贡献

    我们考虑,对于32个位置,选择k个异或为1的选法有多少

    我们记cnt[i]表示第i位为1的数有多少个

    那么显然,每一位对于答案的为2^i*方案数使得这一位为1

    若要这一位为1,显然就需要选出奇数个1,那么我们假设选出了j个,那么0就要选k-j个

    所以这一位答案就是2^i*(ΣC(j,cnt[i])*C(k-j,n-cnt[i]){j&1=1}

    最后累加就好

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define LL __int128
    #define M 998244353 
    using namespace std;
    int cnt[32],n,s[100010],k;
    LL js[100010],inv[100010],S=0,s1,s2;
    LL pow(LL x,int k){
    	LL s=1;
    	for(;k;x=x*x%M,k>>=1) if(k&1) s=s*x%M;
    	return s;
    }
    LL C(int m,int n){
    	if(n<0 || m>n || m<0) return 0;
    	return js[n]*inv[m]%M*inv[n-m]%M;
    }
    int main(){
    	freopen("card.in","r",stdin);
    	freopen("card.out","w",stdout);
    	scanf("%d%d",&n,&k); --k;
    	for(int i=*js=*inv=1;i<=n;++i){
    		scanf("%d",s+i);
    		js[i]=js[i-1]*i%M;
    		for(int j=0;s[i];++j,s[i]>>=1) cnt[j]+=(s[i]&1);
    	}
    	inv[n]=pow(js[n],M-2); 
    	for(int i=n;i;--i) inv[i-1]=inv[i]*i%M;
    	for(int i=0;i<32;++i){
    		s1=s2=0;
    		for(int j=0;j<=k;j+=2) s1=(s1+C(j,cnt[i]-1)*C(k-j,n-cnt[i]));
    		for(int j=1;j<=k;j+=2) s2=(s2+C(j,cnt[i])*C(k-j,n-cnt[i]-1));
    		S=(S+(1ll<<i)*(s1*cnt[i]%M+s2*(n-cnt[i])%M)%M)%M;
    	}
    	printf("%lld
    ",(int)(S*pow(k+1,M-2)%M));
    }

  • 相关阅读:
    内联模板 C++快速入门46
    delphi演示程序
    delphi演示程序
    容器和算法 C++快速入门47
    Delphi7_Lite_Fullv7.3优化精简全功能版
    Delphi7_Lite_Fullv7.3优化精简全功能版
    容器和算法 C++快速入门47
    [转载 js]alt美化效果
    “谁动了我的奶酪?”的故事
    谁动了我的奶酪[续] 讨论
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7800599.html
Copyright © 2011-2022 走看看