B. Rock and Lever(位运算)

    科技2022-07-17  109

    B. Rock and Lever(位运算)

    思路:位运算。

    考虑 a i , a j a_i,a_j ai,aj的最高为1的位 p i , p j p_i,p_j pi,pj

    如果 p i ≠ p j p_i\neq p_j pi=pj a i & a j < a i ⊕ a j a_i\&a_j<a_i\oplus a_j ai&aj<aiaj

    因为右边的最高位变成为1,而左边是0。

    所以只有当 p i = p j p_i=p_j pi=pj才有贡献,显然贡献是 c n t ( c n t − 1 ) 2 \dfrac{cnt(cnt-1)}{2} 2cnt(cnt1)

    然后求和即可,另外可以用 l o g 2 ( x ) log_2(x) log2(x)快速求得 x x x的最高位。

    #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7; #define mst(a,b) memset(a,b,sizeof a) #define lx x<<1 #define rx x<<1|1 #define reg register #define PII pair<int,int> #define fi first #define se second #define pb push_back #define il inline int t,n; map<int,int>mp; int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1,x;i<=n;i++){ scanf("%d",&x),mp[log2(x)]++; } ll ans=0; for(auto i:mp) ans+=1LL*i.se*(i.se-1)/2; printf("%lld\n",ans); mp.clear(); } return 0; }

    Processed: 0.009, SQL: 8