题目
https://vjudge.net/problem/Gym-101484K
题意
给你n个数 问有多少合法数对
定义合法为 A||B > max(A,B)
思路
高位前缀和 看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int dp[(1<<21)|5],cnt[(1<<21)|5];
// 子集出现的次数 这个数出现的次数
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
int k;
scanf("%d",&k);
dp[k]++;cnt[k]++;
}
ll ans=1ll*n*(n-1)/2;
for(int i=0;i<m;i++)
for(int j=(1<<m)-1;j>0;j--)
if(j&(1<<i))
dp[j^(1<<i)]+=dp[j];
for(int i=0;i<(1<<m);i++)
{
ans-=1ll*(dp[i]-cnt[i])*cnt[i]; //(子集-本身)*本身
ans-=1ll*(cnt[i]-1)*cnt[i]/2; //自己和自己组合
}
printf("%lld\n",ans);
}

本文探讨了在给定一组整数的情况下,如何通过使用高位前缀和技巧来计算满足特定条件的数对数量。具体而言,合法数对是指两个数进行按位或运算后的结果大于这两个数中的最大值。文章提供了详细的算法实现代码,包括初始化数组存储子集出现次数,通过迭代更新高位前缀和,以及最终计算满足条件的数对总数。
927

被折叠的 条评论
为什么被折叠?



