题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5269 ,BestCoder Round #44的B题,关于字典树的应用。
比赛的时候没想出做法,现在补上。
题解:
我们考虑,当lowbit(A xor B) = 2p时,A和B表示的二进制数的后p-1位肯定相同。于是我们可以维护一棵字典树,对于每个数x,可以将其转换为30位的二进制数(不足30位的在前面补0),将该二进制数逆序后插入字典树。统计答案时,对于Ai我们先将其同上述做法转换为30位的二进制数,然后逆序后在字典树中查找,对于路径上的每个结点x,如果它下一步对应的边是v,则和它xor后lowbit为2k的数有cnt(x , !v)个。cnt(x , v)表示x的对应的v这条边的子树个数。
#include <iostream> #include <cstdio> #include <cmath> #include <queue> #include <vector> #include <string> #include <string.h> #include <algorithm> using namespace std; #define LL __int64 const int maxn = 50000 + 10; const int MOD = 998244353; const int sigma_size = 2; struct Trie { int ch[maxn * 30][sigma_size]; LL cnt[maxn * 30] , pow[35]; int size; void init() { size = pow[0] = 1; memset(ch[0] , 0 , sizeof(ch[0])); memset(cnt , 0 , sizeof(cnt)); for(int i = 1 ; i < 33 ; i++) pow[i] = pow[i - 1] << 1; } int index(char c) { return c - '0'; } void insert(char *s) { int i , rt; for(i = rt = 0 ; s[i] != '