HDU6059 Kanade’s trio (Trie)
题目描述
求有多少三元组满足 (i<j<k)and((A[i]xorA[j])<(A[j]xorA[k]))
题目分析
读题一分钟,思考十五分钟。
根据时间猜测是O(nlogn)的算法。那么可能是枚举+二分,或者枚举+Trie。
有位运算的特点确定Trie是一定的。
那么问题就在于枚举什么。思考后发现枚举k即可。
Code十五分钟,Debug十五分钟后发现没有满足(i < j)这个条件。
…
用40分钟查阅题解并改代码。
总花费86min。
代码
#include <stdio.h>
#include <cstring>
typedef long long ll;
const int M = 30;
const int maxn = 500010 * 30;
int ch[maxn][2], cnt[maxn], o_cnt, bit[M + 10][2];
ll sub[maxn][2];
ll Solve(int n){
ll rnt = 0;
for(int cur = 1, i = M - 1; cur && i >= 0; i--){
int d = (n >> i) & 1;
ll t = cnt[ch[cur][d^1]];
rnt += t * (bit[i][d^1] - 1) - sub[ch[cur][d^1]][d^1];
cur = ch[cur][d];
}
return rnt;
}
int NewNode(){
int id = ++o_cnt;
ch[id][0] = ch[id][1] = cnt[id] = sub[id][0] = sub[id][1] = 0;
return id;
}
void Insert(int n){
for(int cur = 1, i = M - 1; i >= 0; i--){
int &nxt = ch[cur][(n >> i) & 1];
if(nxt == 0) nxt = NewNode();
cur = nxt;
cnt[cur]++;
sub[cur][(n >> i) & 1] += bit[i][(n >> i) & 1];
bit[i][(n >> i) & 1]++;
}
}
int main(){
int T; scanf("%d", &T);
while(T--){
int n; scanf("%d", &n);
memset(bit, 0, sizeof(bit));
o_cnt = 0;
NewNode();
ll ans = 0;
for(int i = 1; i <= n; i++){
int t; scanf("%d", &t);
ans += Solve(t);
Insert(t);
}
printf("%lld\n", ans);
}
return 0;
}
反思总结
爆int。仔细检查。
数组开小了。仔细检查,字典树结点数应为n*bit。
输入速度?