【LG4735】最大異或和
阿新 • • 發佈:2018-12-20
【LG4735】最大異或和
題意
題解
維護一個字首異或和\(S_i\)
對於一個詢問操作\(l\)、\(r\)、\(x\)
就是等價於求一個位置\(p\)(\(l\leq p \leq r)\)使得\(S_nxorS_{p-1}xorx\)最大
可將此問題轉化為求\(p\)使\(S_{p-1}\) \(xor\) \(S_n xor x\)最大
先將後半部分求出然後在可持久化\(trie\)上貪心即可
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> using namespace std; inline int gi() { register int data = 0, w = 1; register char ch = 0; while (!isdigit(ch) && ch != '-') ch = getchar(); if (ch == '-') w = -1, ch = getchar(); while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); return w * data; } const int MAX_N = 600005; struct Trie {int ch[2], latest; } t[MAX_N * 24]; int s[MAX_N], rt[MAX_N], N, M, tot; void insert(int i, int k, int p, int q) { if (k < 0) return (void)(t[q].latest = i); int c = s[i] >> k & 1; if (p) t[q].ch[c ^ 1] = t[p].ch[c ^ 1]; t[q].ch[c] = ++tot; insert(i, k - 1, t[p].ch[c], t[q].ch[c]); t[q].latest = max(t[t[q].ch[0]].latest, t[t[q].ch[1]].latest); } int query(int o, int val, int k, int limit) { if (k < 0) return s[t[o].latest] ^ val; int c = val >> k & 1; if (t[t[o].ch[c ^ 1]].latest >= limit) return query(t[o].ch[c ^ 1], val, k - 1, limit); else return query(t[o].ch[c], val, k - 1, limit); } int main () { N = gi(), M = gi(); t[0].latest = -1; rt[0] = ++tot; insert(0, 23, 0, rt[0]); for (int i = 1; i <= N; i++) { int x = gi(); s[i] = s[i - 1] ^ x; rt[i] = ++tot; insert(i, 23, rt[i - 1], rt[i]); } for (int i = 1; i <= M; i++) { char ch[5]; scanf("%s", ch); if (ch[0] == 'A') { int x = gi(); rt[++N] = ++tot; s[N] = s[N - 1] ^ x; insert(N, 23, rt[N - 1], rt[N]); } else { int l = gi(), r = gi(), x = gi(); printf("%d\n", query(rt[r - 1], x ^ s[N], 23, l - 1)); } } return 0; }