• 异或


    问题描述

    给定数列{An}

    求  lowbit( AixorAj

    其中,lowbit(x)=(x) and (-x)

    输入格式

    输出格式

    样例输入

    样例输出

    数据范围

    题解

    Lowbit的含义是取出这个数字二进制下最低位的1

    对于xor,当参加运算的两个数不同时为1

    那么lowbit(AixorAj)就是取出二进制下不相同的最低位

    如果是用模拟之类的算法,大概就是从低位到高位枚举找到两个数二进制下不相同的最低位。

    然后就想到了字典树。。。

    然而我做这题的时候完全忘了有字典树这种东西

    由于是从低位到高位比较,把所有数字从低位到高位插入01字典树,记录每个结点被覆盖的次数,当一个数字走到某一个节点时,因为要求的是不相同的最低位,这个结点对答案是没有贡献的,他的兄弟结点对答案才有贡献。树上的节点都是01结点,仅仅取出结点被覆盖的次数是不够的,要根据结点的深度还原成原数。

     1 #include <cstdio>
     2 #define ll long long
     3 const ll maxn=199907210507;
     4 int n,cnt=1,f[12000015][2],num[12000015];
     5 ll a[100005],ans;
     6 void add(ll x)
     7 {
     8     int now=1,i,j;
     9     for (i=0;i<60;i++)
    10     {
    11         j=((x&(1ll<<i))>>i);
    12         if (!f[now][j]) f[now][j]=++cnt;
    13         num[f[now][j]]++;
    14         now=f[now][j];
    15     }
    16     return;
    17 }
    18 int main()
    19 {
    20     int i,j,k,now;
    21     scanf("%d",&n);
    22     for (i=1;i<=n;i++)
    23       scanf("%lld",&a[i]);
    24     for (i=1;i<=n;i++) add(a[i]);
    25     for (i=1;i<=n;i++)  
    26       for (now=1,j=0;j<60;j++)
    27       {
    28         k=((a[i]&(1ll<<j))>>j);
    29         ans=(ans+(1ll<<j)%maxn*num[f[now][k^1]]%maxn)%maxn;
    30         now=f[now][k];
    31         }
    32       printf("%lld
    ",ans);
    33       return 0;
    34 }
  • 相关阅读:
    MyBatis学习总结_01_MyBatis快速入门
    PHP 真正多线程的使用
    PHP Ajax 跨域问题最佳解决方案
    阿里内贸团队敏捷实践-敏捷回顾
    Linux系统下如何禁止ping命令或允许ping命令的方法
    分享常见的几种页面静态化的方法
    Spring-Boot初始篇
    在CentOS下面编译WizNote Qt Project
    CentOS 7快速搭建Nodejs开发环境
    大数据 Hive 简介
  • 原文地址:https://www.cnblogs.com/rabbit1103/p/9756945.html
Copyright © 2020-2023  润新知