zoj 3870

呵呵呵,神奇的位运算,当时就一脸懵逼地找规律,并不知道&和<<还能有这效果,,,,,,这里就是记录每个数字二进制最大位数的1的位置i,只要其他的数字的i的前面没有1,并且i或者及其以后是0,那么两个数字抑或后肯定比其中任何一个大

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;
int a[maxn],bit[40];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        memset(bit,0,sizeof(bit));
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            for(int l=31; l>=0; l--)
                if(a[i]&(1<<l))//寻找每个数字二进制最高位的1的位置
                {
                    bit[l]++;
                    break;
                }
        }
        int ans=0;
        for(int i=0;i<n;i++)
        {
            int l=31;
            while(l)
            {
                if(a[i]&(1<<l)) break;//再次找到最高位,l即是位置
                l--;
            }
            while(l>=0)
            {
                if(!(a[i]&(1<<l)))//由l向下找,只要是0,那么就符合条件
                {
                    ans+=bit[l];//加上符合条件的个数
                }
                l--;
            }
        }
      printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-17 08:37:48

zoj 3870的相关文章

位运算 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:

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 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 数学思维

题意:给你n 个数 ,让你找出其中有多少组数字   a 异或b   大于max(a, b) 题解:首先了解异或运算的方式    相同为0  不同为1    可以知道如果要增大肯定是要不同的位多于相同的位,其次需要知道     2的n次方等于2的n-1次访加到2的1次访再加1,即最高位影响大于低位之和,也就是说只有某个数字它和其他数字最大位不相同,则异或必然大于max(a, b): 代码: #include<stdio.h> #include<iostream> #include&l

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个数,求这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 3870 异或运算

给你n个数   问有多少种情况  两两异或大于两个数中的最大值: 分析   如果a小于b    及大的为b  要想a^b大于b  及a的最高位(一定为1)与b的对应位不一样   及b的对应位为0  就一定满足   这样就转换为小的数的对应位 先排序   mark[i]表示i这个位置为0的数的个数 #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using

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

2015省赛小感想

上个月26号,我有幸参加了今年的浙江省省赛.第一次参加正式的ACM比赛,心里略有点小激动.我的队友们也是第一次参加,还好同行的还有学长学姐们的队伍. 早上是热身赛,共四道题,第一题很简单,马上就A掉了.但第二题是到概率题( 第二天得知该题是ZOJ 3696 ),而且好像还是概率论中关于什么分布的.然后队友又看了第三第四题,把题意告诉我后,我也一时不知道怎么做.看着已经有队伍已经A出了第二题,甚至第三第四题也有了,我的心态一下子不好了!!! 我记不清当时到底具体在想什么,只知道当时的我心态已经乱了