ZOJ 3870 Team Formation 亦或运算

来源:互联网 发布:php面试基础知识 编辑:程序博客网 时间:2024/05/21 19:15

题目地址:点击打开链接

Team Formation

Time Limit: 2 Seconds      Memory Limit: 131072 KB

For an upcoming programming contest, Edward, the headmaster of Marjar University, is forming a two-man team fromN students of his university.

Edward knows the skill level of each student. He has found that if two students with skill levelA and B form a team, the skill level of the team will be AB, where ⊕ means bitwise exclusive or. A team will play well if and only if the skill level of the team is greater than the skill level of each team member (i.e.AB > max{A, B}).

Edward wants to form a team that will play well in the contest. Please tell him the possible number of such teams. Two teams are considered different if there is at least one different team member.

Input

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains an integer N (2 <= N <= 100000), which indicates the number of student. The next line containsN positive integers separated by spaces. The ith integer denotes the skill level ofith student. Every integer will not exceed 109.

Output

For each case, print the answer in one line.

Sample Input

231 2 351 2 3 4 5

Sample Output

16
题意 :

给出一个数列,每次选出两个数,如果这两个数满足 a^b > max(a,b); 就是满足题意的方案,方案数+1.

如果用暴力,枚举所有的情况,复杂度O(n*(n-1)/2),最坏的情况n=十万,肯定超时。

思路:

转化成二进制来做。亦或就是不进位的加法。对于任意的二进制数a,找一个满足条件的二进制数b,

使a^b > max(a,b),

例如:

对于a = 1 0 0 1 0 1;  寻找符合条件的b,不妨我们只找比a小的b,那么max(a,b) = a   

我们只需关心a的0位,我们在他的0位上,亦或上1,则0^1=1;

比如

1 0 0 1 0 1

^ 1 0 0 0 0   得

1 1 0 1 0 1 =c 。c = a^b > a 符合题意.。所以我们只需在a的0位上亦或上1,只要让b的这一位是1,高位是0,低位随意。

那么,只需要统计有多少个这样的b,每一个a对应的b,数量加起来就是答案

代码:

#include<stdio.h>#include<string.h>int T,n;int a[100100];int count[33];//count[x]记录x长度的二进制数有几个int lenth(int n){int i=0;while(n){n/=2;i++;}return i;}int main(){scanf("%d",&T);while(T--){memset(count,0,sizeof(count));scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&a[i]);int x=lenth(a[i]);//计算a[i]的二进制长度count[x]++;}long long sum=0; for(int i=0;i<n;i++)//对每一个数a寻找满足a^b<max(a,b)的数b,注意a>b{int temp=a[i];int j=1;//当前从右边数第j位(二进制数) while(temp){if(temp%2==0)sum+=count[j];temp/=2;j++;}}printf("%lld\n",sum); }return 0;}






0 0