zoukankan      html  css  js  c++  java
  • 【YbtOJ#10052】卡牌选取

    题目

    题目链接:http://noip.ybtoj.com.cn/problems

    思路

    考虑按位计算贡献。假设第 \(i\) 位有 \(cnt0/1\)\(0/1\),那么枚举选取 \(1\) 的个数,组合数计算即可。
    时间复杂度 \(O(n\log A\log \operatorname{MOD})\),其中 \(A=\max(a_i)\)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=100010,MOD=998244353,LG=30;
    int n,m,cnt1,cnt0,a[N];
    ll ans,fac[N];
    
    ll fpow(ll x,int k)
    {
    	ll ans=1;
    	for (;k;k>>=1,x=x*x%MOD)
    		if (k&1) ans=ans*x%MOD;
    	return ans;
    }
    
    ll C(ll n,ll m)
    {
    	ll inv=fpow(fac[m]*fac[n-m]%MOD,MOD-2);
    	return fac[n]*inv%MOD;
    }
    
    int main()
    {
    	freopen("card.in","r",stdin);
    	freopen("card.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	fac[0]=1;
    	for (int i=1;i<=n;i++)
    		fac[i]=fac[i-1]*i%MOD;
    	for (int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	for (int i=0;i<=LG;i++)
    	{
    		cnt0=cnt1=0;
    		for (int j=1;j<=n;j++)
    			if (a[j]&(1<<i)) cnt1++;
    				else cnt0++;
    		for (int j=1;j<=cnt1;j+=2)
    		{
    			int k=m-j;
    			if (cnt0<k || k<0) continue;
    			ans=(ans+(1LL<<i)%MOD*C(cnt1,j)%MOD*C(cnt0,k))%MOD;
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    P1363-幻象迷宫
    P1582-倒水
    P2123-皇后游戏
    P1233-木棍加工
    P1052-过河
    P1541-乌龟棋
    P1736-创意吃鱼法
    P1417-烹调方案
    LeetCode--043--字符串相乘(java)
    LeetCode--041--缺失的第一个整数(java)
  • 原文地址:https://www.cnblogs.com/stoorz/p/13679063.html
Copyright © 2011-2022 走看看