HDU 6059
题意略。
思路:我们要想令 A[i] ^ A[j] < A[j] ^ A[k](i < j < k),由于A[i]和A[k]都要 ^ A[j],所以我们只需研究一下i,k这两个数之间的关系即可。
我们按位来考虑这两个数之间的关系,可以想到,A[i]和A[k]这两个数的最高不相同位决定了A[i] ^ A[j]与A[j] ^ A[k]的大小关系:
(下面用high[ ]来表示A[i]和A[k]这两个数的最高不相同位)
1.如果high[i] = 1,high[k] = 0,那么A[j]的这一位应该是1。
2.如果high[i] = 0,high[k] = 1,那么A[j]的这一位应该是0。
那么,对于每一个A[k],我们枚举它与前面数的最高不相同位来计算它对最后答案的贡献。
现在看看怎么来达到这个目的:
1.我们需要知道A[i]的个数c1,对A[i]的约束即是在最高不相同位的更高位上与A[k]相同,在最高不相同位上与A[k]相异,这个个数我们可以用字典树来维护。
2.我们需要知道A[j]的个数c2,A[j]需要满足的条件是在最高不同位上与A[k]相异,这个我们可以用一个二维数组Cnt[31][2]来维护,
里面记录着从A[1]~A[k - 1]这k - 1个数中在第i位为j的项的个数。
那A[k]的贡献是不是就是c1 * c2了呢?并不是。
有两个不合理的条件:
1.c2中包含了c1,也就是说c1 * c2中有可能有同一个数选了两次的情况。
2.c1 * c2只保证了i < k && j < k,未能保证i < j这个条件。
为了去掉1中的不合理因素,我们只需要减去c1即可。
为了去掉2中的不合理因素,我们可以用illegal[ ]来记录字典树上这个结点的不合理数。怎么记录呢?
每当我们插入这个结点的时候,当前Cnt[ ][ ]数组中存的值都是在当前结点之前出现过的,它们都是当前结点的不合理数。
所以,A[k]的贡献是c1 * c2 - c1 - illegal[cur_node]。
详见代码:
- #include<bits/stdc++.h>
- #define maxn 500000 * 31
- using namespace std;
- typedef long long LL;
- int Cnt[][];
- struct Trie{
- int relation[maxn][],info[maxn];
- LL illegal[maxn];
- int root,cnt;
- int newnode(){
- relation[cnt][] = relation[cnt][] = -;
- info[cnt] = illegal[cnt] = ;
- return cnt++;
- }
- void init(){
- cnt = ;
- root = newnode();
- }
- void insert(int x){
- int cur = root;
- ++info[cur];
- for(int i = ;i >= ;--i){
- if(relation[cur][(x>>i) & ] == -)
- relation[cur][(x>>i) & ] = newnode();
- cur = relation[cur][(x>>i) & ];
- illegal[cur] += (Cnt[i][(x>>i) & ]);
- ++Cnt[i][(x>>i) & ];
- ++info[cur];
- }
- }
- LL query(int x){
- LL ret = ;
- int cur = root;
- for(int i = ;i >= ;--i){
- int numb = ((x>>i) & ),another = - numb;
- int idx = relation[cur][another];
- LL c = info[idx];
- LL temp = c * (Cnt[i][another]) - c - illegal[idx];
- ret += temp;
- cur = relation[cur][numb];
- if(cur == -) break;
- }
- return ret;
- }
- };
- Trie trie;
- int main(){
- int T;
- scanf("%d",&T);
- while(T--){
- LL ans = ;
- int n;
- scanf("%d",&n);
- trie.init();
- memset(Cnt,,sizeof(Cnt));
- for(int i = ;i < n;++i){
- int temp;
- scanf("%d",&temp);
- ans += trie.query(temp);
- trie.insert(temp);
- }
- printf("%lld\n",ans);
- }
- return ;
- }
- /*
- 1
- 4
- 9 8 7 3
- */
HDU 6059的更多相关文章
- HDU 6059 - Kanade's trio | 2017 Multi-University Training Contest 3
思路来自题解(看着题解和标程瞎吉尔比划了半天) /* HDU 6059 - Kanade's trio [ 字典树 ] | 2017 Multi-University Training Conte ...
- hdu 6059 Kanade's trio
题 OwO http://acm.hdu.edu.cn/showproblem.php?pid=6059 解 由于每个数字最多是30位,枚举数字每一位考虑, 建一棵记录前缀(位的前缀,比如10拆成10 ...
- HDU 6059 17多校3 Kanade's trio(字典树)
Problem Description Give you an array A[1..n],you need to calculate how many tuples (i,j,k) satisfy ...
- hdu 6059 Kanade's trio(字典树)
Kanade's trio Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)T ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
随机推荐
- Java 虚拟机部分面试题
Java虚拟机部分的面试内容包括三部分:GC.类加载机制以及内存 Java内存区域 JVM内存分为哪几部分,这些部分分别都存储哪些数据? 线程隔离的数据区:程序计数器.Java虚拟机栈.本地方法栈. ...
- json与js对象间的转化
- Pinyin4j简单使用教程
Pinyin4j是一个流行的Java库,支持中文字符和拼音之间的转换,拼音输出格式可以定制,在项目中经常会遇到需求用户输入汉字后转换为拼音的场景,这时候Pinyin4j就可以派上用场 有自己私服的可以 ...
- HZOJ 单
两个子任务真的是坑……考试的时候想到了60分的算法,然而只拿到了20分(各种沙雕错,没救了……). 算法1: 对于测试点1,直接n遍dfs即可求出答案,复杂度O(n^2),然而还是有好多同学跑LCA/ ...
- Java oop 多态
1.多态指对象的多种形态:引用多态与方法多态 注意: A:继承是多态的实现基础 B:方法重写也是多态的体现 2.引用多态 A:父类的引用可以指向本类的对象:父类 对象名 = new 父类( ...
- itextpdf 解析带中文的html问题
官网连接 官网上有很多DEMO,下面就说几个我碰到的问题! Question: 1. 中文不显示 或者是乱码(本打算用Apache pdfbox来实现业务,但是折腾了一个上午也没解决中午乱码问题,就找 ...
- 常用服务部署脚本(nodejs,pyenv,go,redis,)
根据工作总结的常用安装脚本,要求linux-64系统 #!/bin/bash path=/usr/local/src node () { cd $path #wget https://nodejs.o ...
- js获得页面get跳转的参数
通过js获得页面跳转参数 页面通过window.location.href或通过window.parent.location.href进行页面跳转,在新的页面如何获得相应的参数呢? window.lo ...
- ByteBuf
ByteBuf readerIndex ,读索引 writerIndex ,写索引 capacity ,当前容量 maxCapacity ,最大容量,当 writerIndex 写入超过 capaci ...
- 微服务世界之Nacos初见
Nacos 1.概要 Dubbo 服务的注册和发现/rpc通信/负载均衡/限流/熔断/降级 Spring Cloud alibaba 服务注册发现中间件 zookeeper/eureka/consul ...