洛谷P4592 [TJOI2018]异或 【可持久化trie树】
2018-05-17 10:44
288 查看
题目链接
题解
可持久化trie树裸题
写完就A了
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<map> #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt) #define REP(i,n) for (int i = 1; i <= (n); i++) #define mp(a,b) make_pair<int,int>(a,b) #define cls(s) memset(s,0,sizeof(s)) #define cp pair<int,int> #define LL long long int using namespace std; const int maxn = 100005,B = 30,maxm = 5000005,INF = 1000000000; inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag; } int bin[50]; struct Trie{ int ch[maxm][2],sum[maxm],rt[maxn],cnt; int ins(int pre,int x){ int tmp,u; tmp = u = ++cnt; for (int i = B; i >= 0; i--){ ch[u][0] = ch[pre][0]; ch[u][1] = ch[pre][1]; sum[u] = sum[pre] + 1; int t = x & bin[i]; t >>= i; pre = ch[pre][t]; u = ch[u][t] = ++cnt; } sum[u] = sum[pre] + 1; return tmp; } int query(int pre,int u,int x,int dep){ if (dep < 0) return 0; int t = x & bin[dep]; t >>= dep; if (sum[ch[u][t ^ 1]] - sum[ch[pre][t ^ 1]]) return bin[dep] + query(ch[pre][t ^ 1],ch[u][t ^ 1],x,dep - 1); return query(ch[pre][t],ch[u][t],x,dep - 1); } int Query(int a,int b,int c,int d,int x,int dep){ if (dep < 0) return 0; int t = x & bin[dep]; t >>= dep; if (sum[ch[a][t ^ 1]] + sum[ch[b][t ^ 1]] - sum[ch[c][t ^ 1]] - sum[ch[d][t ^ 1]]) return bin[dep] + Query(ch[a][t ^ 1],ch[b][t ^ 1],ch[c][t ^ 1],ch[d][t ^ 1],x,dep - 1); return Query(ch[a][t],ch[b][t],ch[c][t],ch[d][t],x,dep - 1); } }T1,T2; int n,Q,val[maxn]; int h[maxn],ne = 1; struct EDGE{int to,nxt;}ed[maxn << 1]; inline void build(int u,int v){ ed[++ne] = (EDGE){v,h[u]}; h[u] = ne; ed[++ne] = (EDGE){u,h[v]}; h[v] = ne; } int dfn[maxn],fa[maxn][18],at[maxn],siz[maxn],dep[maxn],cnt; void dfs(int u){ dfn[u] = ++cnt; at[cnt] = u; siz[u] = 1; T1.rt[u] = T1.ins(T1.rt[fa[u][0]],val[u]); REP(i,17) fa[u][i] =fa[fa[u][i - 1]][i - 1]; Redge(u) if ((to = ed[k].to) != fa[u][0]){ fa[to][0] = u; dep[to] = dep[u] + 1; dfs(to); siz[u] += siz[to]; } } int lca(int u,int v){ if (dep[u] < dep[v]) swap(u,v); for (int i = 0,d = dep[u] - dep[v]; (1 << i) <= d; i++) if (d & (1 << i)) u = fa[u][i]; if (u == v) return u; for (int i = 17; i >= 0; i--) if (fa[u][i] != fa[v][i]){ u = fa[u][i]; v = fa[v][i]; } return fa[u][0]; } int main(){ bin[0] = 1; REP(i,30) bin[i] = bin[i - 1] << 1; n = read(); Q = read(); REP(i,n) val[i] = read(); for (int i = 1; i < n; i++) build(read(),read()); dfs(1); for (int i = 1; i <= n; i++) T2.rt[i] = T2.ins(T2.rt[i - 1],val[at[i]]); int opt,x,y,z,o; while (Q--){ opt = read(); x = read(); y = read(); if (opt & 1){ printf("%d\n",T2.query(T2.rt[dfn[x] - 1],T2.rt[dfn[x] + siz[x] - 1],y,B)); } else { z = read(); o = lca(x,y); printf("%d\n",T1.Query(T1.rt[x],T1.rt[y],T1.rt[o],T1.rt[fa[o][0]],z,B)); } } return 0; }
相关文章推荐
- 可持久化01Trie树+LCA【p4592】[TJOI2018]异或
- BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】
- BZOJ5338:[TJOI2018]异或——题解
- bzoj 3261 最大异或和 可持久化trie树
- [BZOJ3261]最大异或和(可持久化trie树)
- 【bzoj3261】【最大异或和】可持久化trie树+贪心
- 【bzoj4103】[Thu Summer Camp 2015]异或运算 可持久化Trie树
- BZOJ 3261 最大异或和 可持久化Trie树
- 可持久化01Trie树【p4735(bzoj3261)】最大异或和
- 【BZOJ 4103】[Thu Summer Camp 2015]异或运算 可持久化trie树
- 【bzoj3261】最大异或和 可持久化Trie树
- BZOJ 3261 浅谈可持久化TRIE树最大连续异或和
- BZOJ3261 最大异或和 【可持久化trie树】
- bzoj3261最大异或和&&可持久化Trie树详解
- bzoj3261 最大异或和【可持久化trie树】
- 【BZOJ4103】[Thu Summer Camp 2015]异或运算 可持久化Trie树
- [BZOJ4103][Thu Summer Camp 2015]异或运算 可持久化Trie树
- BZOJ4103 [Thu Summer Camp 2015]异或运算 【可持久化trie树】
- bzoj 3261: 最大异或和 (可持久化trie树)
- 【BZOJ4103】异或运算(THUSC2015)-可持久化trie树+位运算