2017 Multi-University Training Contest - Team 3:1004. Kanade's trio(01字典树)
2017-08-04 00:19
525 查看
(具体规则or什么是字典树:http://blog.csdn.net/jaihk662/article/details/53930927)
建立两棵01字典树,对于当前第j个节点,将前面所有数加入第一棵字典树,将后面所有数加入第二棵字典树
之后查询就好了,如果两个数a[i]和a[k]前x位都相同,那么很显然这两个数异或a[j]前x位也都相同
所以你只要找出a[i]和a[k]第一个不同的地方进行异或比较就好
在字典树上的操作就是:对于两棵字典树所有相同的前缀,答案加上两棵树下一个不同的节点的权值积
例如:两棵树都经过了10010(root->R->L->L->R->L),那么
ans += sum1(100101)*sum2(100100)或者ans += sum1(100100)*sum2(100101)(具体加哪一个取决于a[j])
但相同前缀个数可能过多,所以要在树上求后缀
tre[]:字典树
val[now][t]:第t棵字典树now节点的权值(t=0那棵用来存前面的数)
frd[x]:节点x的兄弟(x和frd[x]父亲是同一个)
rek[i][]:存后缀,前i-1位都相同第i个数不同对答案的贡献
#include<stdio.h> #include<string.h> #define LL long long int root, tre[3000055][2], val[3000055][2], rek[35][2], a[560000]; LL frd[3000055]; void Insert(LL x, int t) { int i, c, now = 0; for(i=30;i>=0;i--) { c = 0; if(x&(1<<i)) c = 1; if(tre[now][c]==0) { tre[now][c] = ++root; if(tre[now][c^1]) { frd[root] = tre[now][c^1]; frd[tre[now][c^1]] = root; } } now = tre[now][c]; val[now][t] += 1; rek[i][c^t] += val[frd[now]][t^1]; } } void Delete(LL x, int t) { int c, i, now = 0; for(i=30;i>=0;i--) { c = 0; if(x&(1<<i)) c = 1; now = tre[now][c]; val[now][t] -= 1; rek[i][c^t] -= val[frd[now]][t^1]; } } LL Query(LL x) { int i, c; LL sum = 0; for(i=30;i>=0;i--) { c = 0; if(x&(1<<i)) c = 1; sum += rek[i][c]; } return sum; } int main(void) { LL ans; int T, n, i; scanf("%d", &T); while(T--) { ans = root = 0; memset(tre, 0, sizeof(tre)); memset(val, 0, sizeof(val)); memset(rek, 0, sizeof(rek)); memset(frd, 0, sizeof(frd)); scanf("%d", &n); for(i=1;i<=n;i++) scanf("%d", &a[i]); for(i=2;i<=n;i++) Insert(a[i], 1); Insert(a[1], 0); for(i=2;i<=n;i++) { Delete(a[i], 1); ans += Query(a[i]); Insert(a[i], 0); } printf("%lld\n", ans); } }
相关文章推荐
- 2017 Multi-University Training Contest - Team 5 1008 【思维 + 01背包思想】
- 转载hdu 6059 字典树(好题要慢慢消化)2017 Multi-University Training Contest - Team 3
- 2017 Multi-University Training Contest - Team 6:String(字典树)
- HDU 6127 Hard challenge(思维+计算几何)——2017 Multi-University Training Contest - Team 7
- 2017 Multi-University Training Contest - Team 6 HDU 6103 Kirinriki (尺取法)
- 【2017 Multi-University Training Contest - Team 6】Classes
- 【2017 Multi-University Training Contest - Team 4】Time To Get Up
- 2017 Multi-University Training Contest - Team 1:1002 Balala Power!
- 2017 Multi-University Training Contest - Team 1 之Add More Zero
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- 2017 Multi-University Training Contest - Team 1(hdu 6043 KazaQ's Socks)
- hdu 6047 Maximum Sequence(2017 Multi-University Training Contest - Team 2)
- hdu 6045 Is Derek lying?(2017 Multi-University Training Contest - Team 2)
- 2017 Multi-University Training Contest - Team 2 1001 && HDU6045
- hdu 6055 Regular polygon(判断正方形)(2017 Multi-University Training Contest - Team 2)
- 2017 Multi-University Training Contest - Team 9:Two strings
- 2017 Multi-University Training Contest - Team 7 Kolakoski
- 2017 Multi-University Training Contest - Team 1
- 2017 Multi-University Training Contest - Team 3 hdu6060 RXD and dividing
- 2017 Multi-University Training Contest - Team 3(补题系列)