【01-Trie】維護異或和
阿新 • • 發佈:2020-12-05
題目大意
初始有一個空陣列,現有兩種操作:
- 向陣列中插入一個數字
- 陣列中的所有數字+1
給出 n 個操作,輸出每次操作後整個陣列的異或和。
題解
01字典樹板子題
程式碼
//#include<bits/stdc++.h> #include<map> #include<set> #include<vector> #include<stack> #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; #define pb push_back typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int seed=233; const int N=2e5+10; struct Trie { int ch[N*32][2],w[N*32],rt,tot,maxh; ll val[N*32]; #define ls ch[u][0] #define rs ch[u][1] Trie() { rt=tot=0,maxh=31; } int mknode() { ++tot; ch[tot][0]=ch[tot][1]=w[tot]=val[tot]=0; return tot; } void mallain(int u) { val[u]=0,w[u]=w[ls]+w[rs]; if(rs) val[u] ^= (val[rs]<<1) | (w[rs]&1); if(ls) val[u]^= val[ls]<<1; } void insert(int &u,int x,int dep)//插入某數字 { if(!u) u=mknode(); if(dep==maxh) return (void)w[u]++; insert(ch[u][x&1],x>>1,dep+1); mallain(u); } void erase(int &u,int x,int dep)//刪除某數字 { if(dep==maxh) return (void)w[u]--; erase(ch[u][x&1],x>>1,dep+1); mallain(u); } void add(int u)//全域性加1 { if(rs) add(rs); swap(ls,rs); mallain(u); } }trie; int main() { int n; scanf("%d",&n); while(n--){ int op; scanf("%d",&op); if(op==1){ trie.add(trie.rt); }else{ int x; scanf("%d",&x); trie.insert(trie.rt,x,1); } printf("%lld\n",trie.val[1]); } return 0; } /* 3 2 2 2 1 1 */