• ZOJ


    题意:给定N个数,求这N个数中满足A ⊕ B > max{AB})的AB有多少对。(A,B是N中的某两个数)

    分析:

    1、异或,首先想到转化为二进制。

    eg:110011(A)和 1(B)--------A中从右数第三个数是0,若某个数B(eg:110,101,111,……)从左向右数第三个数为1,那么两个异或一定满足A ⊕ B > max{AB})。

          还有哪些数B能让A ⊕ B > max{AB})呢?

    根据上述,同理,从右数第四个为1的数B也符合要求。

    很容易想到,将N个数排序,对于A前面的数,二分统计在1000~1111和100~111中的数,这些数B都能使A ⊕ B > max{AB}),

    不过,这太耗时间了~

    2、试想,只要从右数第三个数是1的数都符合,那二进制位数为3的数当然满足从右数第三个数是1呀,因为没有前导0呀,eg:100,101,110,111

    所以,只要预处理出N个数中二进制位数为3的数,个数为x,那么这些数与A一定能使能使A ⊕ B > max{AB})。

    再扩展一下,A其实是满足从右数第三个数为0的一类数,我们预处理时也统计出来,个数为y,那么x*y就是对于二进制从右数第三位中满足要求的AB对数。

    对于二进制中的每一位都是同理,最后求和即可。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define lowbit(x) (x & (-x))
    const double eps = 1e-8;
    inline int dcmp(double a, double b){
        if(fabs(a - b) < eps) return 0;
        return a > b ? 1 : -1;
    }
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
    const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const int MOD = 1e9 + 7;
    const double pi = acos(-1.0);
    const int MAXN = 30 + 10;
    const int MAXT = 10000 + 10;
    using namespace std;
    int w[MAXN];
    int id[MAXN];
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            memset(w, 0, sizeof w);
            memset(id, 0, sizeof id);
            int n;
            scanf("%d", &n);
            while(n--){
                int x;
                scanf("%d", &x);
                int cnt = 1;
                while(x){
                    if(x % 2 == 0) ++id[cnt];
                    ++cnt;
                    x >>= 1;
                }
                ++w[cnt - 1];
            }
            LL ans = 0;
            for(int i = 0; i < 32; ++i){
                ans += (LL)w[i] * id[i];
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    mysql 行转列 列转行
    JAVA中使用JSch库实现SSH功能
    sqlmap详解
    Max+Decode的妙用.(紀錄分組).
    apache mina sshd ,纯java的ssh工具包
    Nginx 日志分析及性能排查
    PHP在Apache中两种工作方式的区别(CGI模式、Apache 模块DLL)
    如何将本地做好的网站挂到服务器上
    Drupal
    程序员的十种级别,
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/6782745.html
Copyright © 2020-2023  润新知