zoj3870 找规律、二分

来源:互联网 发布:淘宝如何快速刷销量 编辑:程序博客网 时间:2024/05/20 23:36

题意:给你一个数组,问数组中有多少对(x,y)使 x ⊕ y > max(x,y)
题解: 我的解法是 先对数组从小到大排序
然后,对于一个数A,假设它的二进制表示为 11101101
二进制里有两个0
从右往左看,对于第一个0,它在第2位,那么对于任何二进制只有2位的数B(10,11),都能使 A⊕B>max(A,B) (其实max(A,B)=A,因为这样产生的B不可能比A大,A⊕B后,A的一个二进制0变成了1,肯定变大了)
对于第二个0,它在第5位,那么对于任何二进制只有5位的数B(10000,10001…..11111),都能使 A⊕B>max(A,B)
就这样遍历数组中的每一个数即可

#include<bits/stdc++.h>const int INF  = 0x3f3f3f3f;const int Maxn = 1000005;#define ll long longusing namespace std;int x[Maxn], pos[33];int main() {    int T, N;    cin >> T;    while (T--) {        scanf("%d", &N);        for (int i = 0; i < N; i++) scanf("%d", &x[i]);        sort(x, x + N);        long long ans = 0;        for (int i = 1; i < N; i++) {            memset(pos, 0, sizeof(pos));            int k = x[i], cnt = 0, p = 0; //  cnt -> x[i]二进制中0的个数,p表示0的位置            while (k) {                if ((k & 1) == 0) pos[cnt++] = p;                k >>= 1;                p++;            }            for (int j = 0; j < cnt; j++) {                int a = 1 << pos[j], b = (1 << (pos[j] + 1)) - 1;                ans += upper_bound(x, x + i, b) - lower_bound(x, x + i, a);            }        }        printf("%lld\n", ans);    }}
0 0
原创粉丝点击