ZOJ 3870(数学)

来源:互联网 发布:网站编程软件 编辑:程序博客网 时间:2024/06/15 16:52
//题意:从一堆数字中任选两个数字,使其异或后的值大于这两个数字的任意一个  求这样的数字有多少对//方法: 如果要两个数字异或后的值大于任意一个 //             只需要大的那个元素的最高位大于小的那个元素的最高位且//             小的元素的最高位对应的大的元素的该位上的数字为0即可//             利用数组bits[i](二进制最高位为i的数字有多少个)进行累加即可#include <stdio.h>#include <math.h>#include <string.h>#include <algorithm>#include <iostream>using namespace std;int bits[35];int ss[100005];int cnt[100005];long long ans;void find_(int x){    for(int i = cnt[x]; i>= 0; i--)    {        if( !((1 << i) & ss[x]) ){            ans += bits[i];        }    }}int cal(int x){    int i = 31;    while(i >= 0)    {        if(x & (1 << i)){            bits[i]++;            return i;        }        else i--;    }}int main(){    int t, n, temp;    scanf("%d", &t);    while(t--)    {        scanf("%d", &n);        memset(bits, 0, sizeof bits);        for(int i = 0; i < n; i++)        {            scanf("%d", &ss[i]);            cnt[i] = cal(ss[i]);        }        ans = 0;        for(int i = 0; i < n; i++)            find_(i);        printf("%d\n", ans);    }    return 0;}


0 0
原创粉丝点击