hdu6059

题意

给定数组 \(A\) ,问有多少对下标 \((i, j, k)\) 满足 \(i < j < k\) 且 \((A[i] \ xor \ A[j]) < (A[j] \ xor \ A[k])\) 。

分析

首先建一棵字典树,从高到低位插入所有数字(长度要相同,所以前面不足用 \(0\) 补),在插入的过程中计算对于每个 \(k\) 前面有多少个 \(j\) 可以配对(也就是在前面插入的值中寻找),只要将当前位取反就能找到有多少个 \(j\) 与之对应(可以用一个 \(cnt\) 数组记录每一位分别为 \(0\) 和 \(1\) 的次数)。

查询时,从头开始删除,每删除一次(一是要去标记一下,而是去掉这个数作为 \(k\) 的影响),再去查询对应的数,我们求的实际是对于每个 \(A[i]\) 有几个 \(A[j] \ A[k]\) 与之对应 。在去计算答案的时候前面的标记就有作用了,已经标记作为 \(j\) 的与后面的 \(k\) 产生的配对要减掉,因为要满足 \(i < j\) ,前面标记过的 \(j < i\) ,所以前面的 \(j\) 与 \(k\) 的配对是无效的。

大致的意思就是对 \(i\) 去寻找 \(k\) ,然后删掉不满足条件的 \(j\) 。

建议结合代码画图理解一下。

code

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int MAXN = 2e6 + 10;
int n;
int a[MAXN];
int root, L;
int nxt[MAXN][2], cnt[MAXN][2], has[MAXN];
ll sum[MAXN];
ll ans;
int newnode() {
nxt[L][0] = nxt[L][1] = 0;
return L++;
}
void init() {
L = 1;
root = newnode();
memset(sum, 0, sizeof sum);
memset(cnt, 0, sizeof cnt);
memset(has, 0, sizeof has);
}
void insert(int x, int k) {
int tp[32], c = 0;
memset(tp, 0, sizeof tp);
while(x) {
tp[c++] = x % 2;
x >>= 1;
}
int now = root;
for(int i = 30; i >= 0; i--) {
int d = tp[i];
if(!nxt[now][d]) nxt[now][d] = newnode();
now = nxt[now][d];
cnt[i][d]++;
sum[now] += k * cnt[i][d ^ 1];
has[now] += k;
}
}
void query(int x) {
int tp[32], c = 0;
memset(tp, 0, sizeof tp);
while(x) {
tp[c++] = x % 2;
x >>= 1;
}
int now = root;
for(int i = 30; i >= 0; i--) {
int d = tp[i];
int tmp = nxt[now][d ^ 1];
if(tmp) {
ans += sum[tmp] - 1LL * has[tmp] * cnt[i][d];
}
now = nxt[now][d];
if(!now) break;
}
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
init();
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
insert(a[i], 1);
}
ans = 0;
memset(cnt, 0, sizeof cnt);
for(int i = 0; i < n; i++) {
insert(a[i], -1);
query(a[i]);
}
printf("%lld\n", ans);
}
return 0;
}

hdu6059( Trie )的更多相关文章

  1. 【python】Leetcode每日一题-前缀树(Trie)

    [python]Leetcode每日一题-前缀树(Trie) [题目描述] Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的 ...

  2. LA3942-Remember the Word(Trie)

    题意: 有s个不同的单词,给出一个长字符串把这个字符串分解成若干个单词的连接(可重复使用),有多少种分解方法 分析: dp[i]表示i开始的字符串能分解的方法数 dp[i]=sum(dp[i+len( ...

  3. HDU 1671 Phone List (Trie)

    pid=1671">Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  4. hdu 1251 统计难题 (字典树(Trie)<PS:C++提交不得爆内存>)

    统计难题Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submis ...

  5. 字典树(Trie)的java实现

    一.定义 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用 ...

  6. HDU 4825-Xor Sum(trie)

    题意: 给你一组数,开始询问给一个数  求组中与该数异或值最大的数. 分析:根据异或的特点 要想得到的异或值最大 尽可能的让两个数的每位都相反 先把给定的一组数建树,数的最后一位对应的节点保存这个数的 ...

  7. 【UER #1】跳蚤OS(Trie)

    跳蚤OS 是跳蚤国自主研发的功能强大的操作系统. 跳蚤OS的文件系统与普通的文件系统类似,是个文件夹套文件夹的结构.文件系统根目录称为“//”.我们可以用文件路径来表明文件所在的位置,比如“/flea ...

  8. UVA - 11732 "strcmp()" Anyone? (trie)

    https://vjudge.net/problem/UVA-11732 题意 给定n个字符串,问用strcmp函数比较这些字符串共用多少次比较. strcmp函数的实现 int strcmp(cha ...

  9. hihoCoder 1014 Trie树 (Trie)

    #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi和小Ho是一对好朋友.出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮 ...

随机推荐

  1. Hibernate高级应用

    数据模型与领域模型的关系 领域模型是一个分析模型,它帮助需求分析人员.用户认识现实业务的工具,描述的是业务中设计的试题及其相互之间的关系,它是需求分析的产物.领域模型是需求分析人员与用户交流的有力工具 ...

  2. vue的nextTick的实现

    vue的nextTick是用浏览器支持的方法模拟nodejs的process.nextTick 老版本的vue用如下方法来模拟 Promise.thenMutationObserver(Mutatio ...

  3. Ubuntu下安装LNMP之nginx的卸载

    我在安装Nginx时,是采用自己从网上down下自己需要的nginx版本进行编译安装的,如果使用过apt库来进行安装的话可以参考这篇文章:ubuntu中彻底删除nginx 假如是编译安装的童鞋,可以按 ...

  4. Wpremig和Jhadgre的藏宝图(最大流+二分)

    Wpremig和Jhadgre的藏宝图 题目链接:https://ac.nowcoder.com/acm/contest/333/M Description: Jhadgre在生日那天收到了一张神秘的 ...

  5. 移动端去掉a标签点击时出现的背景

    之前做移动端的Portal时,手机上测试,点击a标签总是出现一个背景框 在CSS中添加 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);就可以了 a:act ...

  6. php2go - Go 实现 PHP 常用内置函数

    [转]http://www.syyong.com/Go/php2go-Use-Golang-to-implement-PHP-s-common-built-in-functions.html 使用Go ...

  7. SpringMVC异常报406 (Not Acceptable)的解决办法

    使用SpsringMVC,使用restEasy调试,controller请求设置如下: @RequestMapping(value="/list",method=RequestMe ...

  8. [BZOJ3238][Ahoi2013]差异解题报告|后缀数组

    Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首 ...

  9. bootstrap row 行间距

    <div class="clearfix" style="margin-bottom: 10px;"></div>清除浮动加个margi ...

  10. python 调用Linux shell

    有时候难免需要直接调用Shell命令来完成一些比较简单的操作,比如mount一个文件系统之类的.那么我们使用Python如何调用Linux的Shell命令?下面来介绍几种常用的方法: 1. os 模块 ...