题意:一个树,q次询问,求xi xor u的子树的max值
思路:考虑可以直接dfs,映射到数轴上,然后就是裸的可持久化trie了。。时间复杂度nlogn,同理nlognlogn可以线段树套trie(这个题没按这个写。。应该可以?参考51nod1295,第一次写可持久化trie就是树套树水过去的。。)同理,如果多个log时间复杂度可以就可以暴力启发式合并。。
可持久化trie代码:
#include#define PB push_back#define MEM(x) memset(x,0,sizeof(x));using namespace std;char tmp[33];void tr(int x){ tmp[32]='\0'; for(int i=31;i>=0;i--){ tmp[i]=((x&1)+'0'); x>>=1; }}struct Trie_Persistent{ const static int LetterSize = 2; const static int TrieSize = 40 * ( 1e5 + 50); int tot; struct node{ int ptr[LetterSize]; int cnt[LetterSize]; }tree[TrieSize]; inline int GetLetterIdx(int c){return c - '0';} int zinsert(const char * str ,int f){ int len = strlen( str ); int res = tot++; tree[res] = tree[f]; int cur = res; for(int i = 0 ; i < len ; ++ i){ int idx = GetLetterIdx( str[i] ); int p = tot ++ ; tree[cur].cnt[idx] ++ ; tree[cur].ptr[idx] = p; f = tree[f].ptr[idx]; tree[p] = tree[f]; cur = tree[cur].ptr[idx]; } return res; } int zfind(const char * str , int l ,int r){ int len = strlen(str); int ret=0; for(int i = 0 ; i < len ; ++ i){ int idx = (GetLetterIdx(str[i])); int cnt = tree[r].cnt[idx^1] - tree[l].cnt[idx^1]; if(cnt==0){ l = tree[l].ptr[idx]; r = tree[r].ptr[idx]; } else{ ret|=(1<<(31-i)); l = tree[l].ptr[idx^1]; r = tree[r].ptr[idx^1]; } } return ret; } void init(){ tot = 1; for(int i = 0 ; i < LetterSize ; ++ i) tree[0].ptr[i] = 0 , tree[0].cnt[i] = 0; }}trie;const int maxn=1e6+7;int a[maxn],R[maxn],L[maxn],tim,n,q,x,y;int root[maxn];vector e[maxn];void dfs(int x){ L[x]=tim; for(int i=0;i