一共有 n 张卡牌,每张卡牌上有一个正整数 a[i] ,每次可以从中选出 k 张卡牌。一种选取方案的幸运值为这 k 张卡牌上数的按位异或和。
求所有选取方案的幸运值之和,对998244353取模。
1.拆位(qwq考场上因为拆位整体偏左一位挂了整整50pts)
2.对于每一个二进制位,先不考虑怎么选出来 k 个,而是考虑每个0/1对答案有多少贡献
3.对于每一位上的01串而言,先考虑所有1的贡献,因为异或操作相当于看是否有奇数个一。当我们要选出奇数个1(假设本位有a个1),组合数
。剩下的 k-i 从0中选即可
TLE 90 pts
- #include
- using namespace std;
- #define int long long
- const int N=1000010;
- const int mod=998244353;
- int n,m,k,a[N],num[N],c[N],cc[N],ans;
- int qp(int aa,int b)
- {
- int res=1;
- while(b)
- {
- if(b&1) res=res*aa%mod;
- aa=aa*aa%mod;
- b>>=1;
- }
- return res;
- }
- int C(int a,int b)
- {
- if(areturn 0;
- if(b==0) return 1;
- if(a==b) return 1;
- return (c[a]*qp(c[b],mod-2)%mod)*qp(c[a-b],mod-2)%mod;
- }
- signed main()
- {
- freopen("card.in","r",stdin);
- freopen("card.out","w",stdout);
- scanf("%lld%lld",&n,&k);
- for(int i=1;i<=n;i++)
- {
- scanf("%lld",&num[i]);
- // int tmp=num[i],j=0;
- // while(tmp)
- // {
- // a[++j]+=(tmp&1);
- // tmp>>=1;
- // }
- // m=max(m,j);
- for(int j=0;j<=31;j++) if(num[i]&(1<
- }
- // printf("%lld\n",m);
- // for(int i=1;i<=m;i++) printf("%lld ",a[i]);
- c[0]=c[1]=1;
- for(int i=2;i<=n;i++) c[i]=(c[i-1]*i)%mod;
- cc[n]=qp(c[n],mod-2)%mod;
- for(int f=0;f<=31;f++)//从后往前推位数 m_max=31
- for(int i=1;i<=k;i+=2)
- ans=(ans+(C(a[f],i)*C(n-a[f],k-i)%mod)*qp(2,f)%mod)%mod;
- printf("%lld\n",ans);
- return 0;
- }
预处理出逆元(AC)
- #include
- using namespace std;
- #define int long long
- const int N=1000010;
- const int mod=998244353;
- int n,m,k,a[N],num[N],c[N],cc[N],ans;
- int qp(int aa,int b)
- {
- int res=1;
- while(b)
- {
- if(b&1) res=res*aa%mod;
- aa=aa*aa%mod;
- b>>=1;
- }
- return res;
- }
- int C(int a,int b)
- {
- if(areturn 0;
- return (c[a]*cc[b]%mod)*cc[a-b]%mod;
- }
- signed main()
- {
- freopen("card.in","r",stdin);
- freopen("card.out","w",stdout);
- scanf("%lld%lld",&n,&k);
- for(int i=1;i<=n;i++)
- {
- scanf("%lld",&num[i]);
- // int tmp=num[i],j=0;
- // while(tmp)
- // {
- // a[++j]+=(tmp&1);
- // tmp>>=1;
- // }
- // m=max(m,j);
- for(int j=0;j<=31;j++) if(num[i]&(1<
- }
- // printf("%lld\n",m);
- // for(int i=1;i<=m;i++) printf("%lld ",a[i]);
- c[0]=c[1]=1;
- for(int i=2;i<=n;i++) c[i]=(c[i-1]*i)%mod;
- cc[n]=qp(c[n],mod-2)%mod;
- for(int i=n;i>=1;i--) cc[i-1]=cc[i]*i%mod;
- cc[1]=1;
- for(int f=0;f<=31;f++)//从后往前推位数 m_max=31
- for(int i=1;i<=k;i+=2)
- ans=(ans+(C(a[f],i)*C(n-a[f],k-i)%mod)*qp(2,f)%mod)%mod;
- printf("%lld\n",ans);
- return 0;
- }
-
相关阅读:
安全好用性价比高的远程协同运维软件有吗?
Swift 周报 第十期
一文了解蛋白功能结构域预测与分析
机械寿命预测(基于NASA C-MAPSS数据的剩余使用寿命RUL预测,Python代码,CNN_LSTM模型,有详细中文注释)
SMTP 协议研究
论文笔记 A Comprehensive Survey on Graph Neural Networks(GNN综述)
【华为机试真题 Python实现】火星文计算【2022 Q1 Q2 | 100分】
npm ERR! code ERESOLVEnpm ERR! ERESOLVE could not resolve dependency
面试必备:《Java 最常见 200+ 面试题全面解析》
C++初阶 | [四] 类和对象(下)
-
原文地址:https://blog.csdn.net/m0_60137414/article/details/126673201