位运算 ZOJ 3870 Team Formation

题目传送门

 1 /*
 2     题意:找出符合 A^B > max (A, B) 的组数;
 3     位运算:异或的性质,1^1=0, 1^0=1, 0^1=1, 0^0=0;与的性质:1^1=1, 1^0=0, 0^1=0, 0^0=0;
 4             假设A < B,一定要满足B的最高位对应A的值是0,这样才可能>B(即0^1=1);
 5             然后比赛时假设A的极限是类似0111111的情况,最后假设有误;
 6             题解是先把每个数最高位(1)的位置统计个数,1<<4 的意思是 000010000;
 7             只要与为0,表示最高位p位置的所有数字和当前a[i]异或一定满足,累加ans;
 8
 9     位运算不熟悉, ‘⊕‘还是别人告诉我是异或的;
10     详细解释:http://blog.csdn.net/LYHVOYAGE/article/details/45285731
11 */
12 #include <cstdio>
13 #include <algorithm>
14 #include <cmath>
15 #include <iostream>
16 #include <cstring>
17 #include <string>
18 #include <map>
19 #include <set>
20 using namespace std;
21
22 const int MAXN = 1e5 + 10;
23 const int INF = 0x3f3f3f3f;
24 int a[MAXN];
25 int bit[31];
26
27 void solve(int x)
28 {
29     int p = 31;
30     while (p >= 0)
31     {
32         if (x & (1<<p))
33         {
34             bit[p]++;    return ;
35         }
36         p--;
37     }
38
39     return ;
40 }
41
42 int main(void)        //ZOJ 3870 Team Formation
43 {
44     //freopen ("B.in", "r", stdin);
45
46     int t, n;
47     scanf ("%d", &t);
48     while (t--)
49     {
50         memset (bit, 0, sizeof (bit));
51         scanf ("%d", &n);
52         for (int i=1; i<=n; ++i)
53         {
54             scanf ("%d", &a[i]);    solve (a[i]);
55         }
56
57         long long ans = 0;
58         for (int i=1; i<=n; ++i)
59         {
60             int p = 31;
61             while (p >= 0)
62             {
63                 if (a[i] & (1<<p))    break;
64                 p--;
65             }
66             while (p >= 0)
67             {
68                 if (!(a[i] & (1<<p)))    ans += bit[p];
69                 p--;
70             }
71         }
72
73         printf ("%lld\n", ans);
74     }
75
76     return 0;
77 }
时间: 2025-01-02 17:02:35

位运算 ZOJ 3870 Team Formation的相关文章

ZOJ 3870 Team Formation(位运算)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5518 For an upcoming programming contest, Edward, the headmaster of Marjar University, is forming a two-man team from N students of his university. Edward knows the skill level of each s

zoj 3870 Team Formation 位运算

//给n个数,找有多少队的两个数的异或值大于它们自己 //对于两个数中小的那个数的最高位在大的数中该位为0 //那么两个数异或所得的数比两个数大 //否则,这个数比大的数小 #include<cstdio> #include<cstring> #include<cstdio> #include<algorithm> using namespace std ; const int maxn = 100010; long long  map[40]; int a

ZOJ 3872 Beauty of Array&amp;&amp;ZOJ 3870 Team Formation

3872链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3872 题目大意:给你n个数,问所有的连续的子序列中的所有元素的和(子序列中有相同元素只计算一次)(n<100000). 即若序列为1  2  3,则组成1,2,3,1 2,2 3,1 2 3,和为20: 若序列为1 2 2,则组成1,2,2,1 2,2 2,1 2 2,和为13: 解题思路:求不重复的序列和很简单,关键是去重. 现在看一个序列: 3  4 

ZOJ 3870 Team Formation

题目链接: http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3870 题解: 如果x xor y>max(x,y),那么就会有x和y的最高位不同(二进制表示),并且对于最高位小的那个数的最高位的位置,最高位大的那个数在相同的位置应为0. 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespac

ZOJ - 3870 Team Formation(异或)

题意:给定N个数,求这N个数中满足A ⊕ B > max{A, B})的AB有多少对.(A,B是N中的某两个数) 分析: 1.异或,首先想到转化为二进制. eg:110011(A)和 1(B)--------A中从右数第三个数是0,若某个数B(eg:110,101,111,……)从左向右数第三个数为1,那么两个异或一定满足A ⊕ B > max{A, B}). 还有哪些数B能让A ⊕ B > max{A, B})呢? 根据上述,同理,从右数第四个为1的数B也符合要求. 很容易想到,将N个

ZOJ 3933 Team Formation

费用流裸体......比赛的时候少写了一句话....导致增加了很多无用的边一直在TLE #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; const int maxn=500+10; int n; int belong[maxn]; in

zoj 3933 Team Formation(最小费用流裸题)

1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 5 #include<string> 6 #include<algorithm> 7 #include<set> 8 #include<map> 9 #include<vector> 10 #include<stack> 11 #include<queue> 12 #

ZOJ3870 Team Formation

1 /** 2 Author: Oliver 3 ProblemId: ZOJ3870 Team Formation 4 */ 5 /* 6 思路 7 1.异或运算,使用^会爆,想到二进制: 8 2.我们可以试着从前往后模拟一位一位的^那么只要当前位结果变大便是: 9 3.一般我们如何利用二进制呢?既然要爆那我们就存1的位置: 10 4.问题是怎么存,如何用? 11 5.我之前想的是每个数的每位1都存,但是那样造成的重复计算还没想出怎么避免.看了一下别人的博客,再尝试把每位数的最高位1存起来.

位运算

位运算的实际应用场景 http://blog.csdn.net/zmazon/article/details/8262185