牛客挑战赛62——A-Pair

题目描述

给定n个整数,第i个为ai​,请你统计有多少对无序对(i,j),满足i≠j且(ai&aj)>(ai⊕aj)。
其中&代表二进制按位与,⊕代表二进制按位异或。
无序对的意思是(i,j)被视为同一对。

输入描述

第一行输入正整数n,接下来一行n个整数表示ai。
1≤n≤2×10^5,0≤ai≤10^9

输出描述

一行一个数字表示答案。

示例1

输入

8
12 7 11 6 5 0 2 8

输出

6

示例2

输入

6
3 7 2 6 1 1

输出

3

说明

(1,1),(3,2),(6,7)是满足条件的三对(这里放的是ai的值而非下标)

解题思路

要想满足题目的要求,这两个数的最高位必须都为1,因为 1 & 1 == 1 > 1 ^ 1 = 0

做法一——计数法(参考AC的小伙伴)

import java.util.*;

public class Main {
    
    static int N = 33;
    // 该数组存储的是二进制位数长度相同(不包含前导零,即最高位一定都为1)的整数个数
    static long[] highestBitCnt = new long[N];
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        for (int i = 0; i < n; i++) {
            int a = in.nextInt();
            int highestBit = 0;
            while (a > 0) {
                highestBit++;
                a >>= 1;
            }
            highestBitCnt[highestBit]++;
        }
        
        // 任何数只要跟0组合,都不满足条件,则0直接不考虑
        long res = 0;
        for (int i = 1; i < N; i++) {
            // 二进制位数长度相同的所有整数组成的无序对个数可以通过数学中的组合来计算
            // 这里由于两个int最大为10^5,如果两者相乘的话乘积就会爆int,所以要开long类型数组
            res += (highestBitCnt[i] * (highestBitCnt[i] - 1) / 2);
        }
        
        System.out.println(res);
    }
    
}
原题链接:https://ac.nowcoder.com/acm/contest/11202/A
posted @ 2022-07-16 10:21  没有你哪有我  阅读(63)  评论(0编辑  收藏  举报