Problem

acm.hdu.edu.cn/showproblem.php?pid=6059

Reference

HDU 6059 Kanade’s trio (字典树, 2017 Multi-Univ Training Contest 3)
2017 Multi-University Training Contest 3 solutions BY 洪华敦(1004题)

Meaning

给一个序列 {An} \{A_{n}\},问有多少个有序数对(i, j, k),满足:

  • i < j < k
  • Ai⨁Aj<Aj⨁Ak A_{i}\bigoplus A_{j}

Analysis

从第 2 个条件看到,Aj 在不等式两端都出现,应该是作为一个调节因子的存在,于是先找 Ai 和 Ak,通过它们的关系来“夹”出符合的 Aj。
看 Ai 和 Ak 的关系,考虑它们最高的不同的位(因为低位影响不及高位大,而相同位的用 Aj 调不出差异),假设是第 p 位,有两种情况:

  1. Ai[p]=1,Ak[p]=0 A_{i}[p] = 1,A_{k}[p] = 0。要满足第 2 条不等式,就要让 Aj[p]=1 A_{j}[p] = 1,根据异或性质,这样可以消掉 Ai 在 p 位这个 1,并且让 Aj 的 p 位变 1,于是满足不等式;
  2. Ai[p]=0,Ak[p]=1 A_{i}[p] = 0,A_{k}[p] = 1。这样 Aj[p] A_{j}[p] 就要为 1,分析同上;

于是看出 Ai 和 Aj 的一个关系: Ai[p]=Aj[p] A_{i}[p] = A_{j}[p](p 还是表示 Ai 和 Ak 最高的不同位)。
于是从前往后地把数插入到字典树中,把当前正在插入的数当做 Ak 来算边插入边算贡献。
上面说要考虑 Ai 和 Ak 最高的不同的位 p,那就把当前正在插入的位当做第 p 位,那么对于这个 Ak 来说,可选的 Ai 就是树上同一条路径下来的、在当前这一位才分岔出去的另一棵子树里记录的那些数。
然后找 Aj,由于 Ai 和 Aj 在第 p 位相同,所以上述 Ai 那棵子树里的数同时也能作为 Aj(这样的 Aj 高位与 Ak 相同);
Aj 还可以从别的子树里找,也就是高位与 Ak 不同的、但第 p 位还是与 Ai 相同的数。可以开个数组记录:num[i][j] = 第 i 位值为 j(0/1)的数的个数。但这些数未必符合 i < j 的条件。字典树结点里多记一个值,即参考博客里的ext,说的是如果把当前的节点当做 Ai(而不是 Ak)的话,那在它之前就已经插入的 p 位也为这个值的数,虽然 p 位值相同,但违反 i < j 的规定,把这些数的个数记下,在算贡献时减去。

Code

#include <cstdio>
#include <cstring>
using namespace std;
const int N = 500000, BIT = 30;struct node
{int cnt;int sj; // smaller j,p 位相同但下标比较小的数的个数int nxt[2]; // child node
} trie[N*BIT+1];int sz;
int dig[BIT]; // 拆下来的二进制位
int num[BIT][2]; // num[i][j]:已插入的第 i 位值为 j 的数的个数
long long ans;void update(int p, int pre)
{// Ai 子树中任选两个分别当 Ai 和 Ajans += (long long)trie[p].cnt * (trie[p].cnt - 1) >> 1;// Ai 子树上的只做 Ai,而在其它子树找 Aj,但要去除 i > j 的ans += (long long)trie[p].cnt * (pre - trie[p].cnt) - trie[p].sj;
}void insert()
{for(int b = BIT - 1, p = 0, d; ~b; --b){d = dig[b];if(!trie[p].nxt[d])trie[p].nxt[d] = sz++;if(trie[p].nxt[1-d])update(trie[p].nxt[1 - d], num[b][1 - d]);p = trie[p].nxt[d];++trie[p].cnt;trie[p].sj += num[b][d] - trie[p].cnt;}
}int main()
{int T;scanf("%d", &T);while(T--){int n;scanf("%d", &n);memset(num, 0, sizeof num);memset(trie, 0, sizeof trie);sz = 1;ans = 0;for(int a; n--; ){scanf("%d", &a);for(int b = 0; b < BIT; ++b, a >>= 1){++num[b][a & 1];dig[b] = a & 1;}insert();}printf("%I64d\n", ans);}return 0;
}

题目的trio莫非就是在暗示trie

hdu 6059 Kanade's trio相关推荐

  1. HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3

    /* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意:给出排列 a[N],求所有区间的第 ...

  2. HDU 6058 Kanade's sum 逆序求第k大

    传送门:HTTP://acm.hdu.edu.cn/showproblem.php PID = 6058 题意:给你一个1-n的排列求所有自子区间的第K大的和 思路:从大到小插入位置维护当前数位置以及 ...

  3. 2017多校第3场 HDU 6058 Kanade's sum 双链表,思维

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题外话:这场多校,真心感觉自己的无力,全队都发挥的很差,结束的时候排名掉到了90多,后期没做出字 ...

  4. Kanade's trio 2017多校#3 trie

    求数组中i<j<k 并且ai^aj<aj^ak的三元组组数 枚举插入ak,让ak中每一位作为最高位,查找字典树内最高位不同的数字数量 注意把ak的每个前缀做一个bad标记 存储让这个 ...

  5. 2017 Multi-University Training Contest - Team 3:1004. Kanade's trio(01字典树)

    感觉很多时候字典树都是这种题的万能解 (具体规则or什么是字典树:http://blog.csdn.net/jaihk662/article/details/53930927) 建立两棵01字典树,对 ...

  6. 2017 Multi-University Training Contest - Team 3 Kanade's sum hd6058

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6058 题目: Kanade's sum Time Limit: 4000/2000 MS (J ...

  7. HDU 4930 Fighting the Landlords(扯淡模拟题)

    Fighting the Landlords 大意: 斗地主....   分别给出两把手牌,肯定都合法.每张牌大小顺序是Y (i.e. colored Joker) > X (i.e. Blac ...

  8. HDU 4389 - X mod f(x)

    题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4389 2012多校,第9场,1010 . 问题是,询问区间内 存在多少个 哈沙德数(Harshad ...

  9. HDU 3129 The Brave Sir Robin’s cAsE cOrReCtOr(字符串处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3129 Problem Description Dissatisfied with the loud a ...

最新文章

  1. BZOJ 1444: [Jsoi2009]有趣的游戏
  2. win7 32位下实现远程线程注入
  3. VTK:Utilities之SaveSceneToFile
  4. 鸿蒙系统多屏协同,官方铁证!鸿蒙 2.0 手机来了,EMUI 11 多屏协同支持鸿蒙手机...
  5. 内推|商汤科技深度学习方向实习生
  6. 阿里云发布ECS企业级产品家族 19款实例族涵盖173个应用场景
  7. codeforces 496 E. Distributing Parts(贪心+set二分)
  8. 【图像修复】基于matlab GUI维纳滤波图像复原【含Matlab源码 851期】
  9. 英文java简历模板下载_JAVA技术人员英文简历模板
  10. 基于MATLAB的汽车出入库计时系统 _matlab课程设计
  11. echarts 3d地球js特效代码
  12. m3u8文件下载及合并
  13. 使用c++语言做概率论 涉及求方差
  14. 2023杭州电子科技大学计算机考研信息汇总
  15. 互联网专家资源分享(二)
  16. 小米、百度、bigo 、滴滴 、快手等iOS 面试后的一次阶段性总结
  17. 微信公众号 隐藏菜单
  18. python 课程设计题目_数据分析师能力培养:业务与技术的完美结合
  19. 简单图+Havel_Hakimi定理
  20. Linux服务器连接校园网

热门文章

  1. cropperjs裁剪后图片变大的问题
  2. mysql对比时间段百分比_如何使用MySQL计算每日最高价格变化百分比?
  3. java gps经纬度坐标转高德坐标_高德经纬度转普通GPS经纬度
  4. 基于语料库的汉语形容词宾语与名词句法语义关系分析
  5. Postgresql中xlog生成和清理逻辑
  6. 杭电2022 海选女主角
  7. gophish企业内部钓鱼邮件测试
  8. 315晚会给我们的几点启示
  9. 那些不能在一起吃的水果搭配
  10. 360全景的原理与展示