您的位置:首页 > 其它

BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

2018-05-19 11:41 295 查看

题目分析:

  很无聊的一道题目。首先区间内单点对应异或值的询问容易想到trie树。由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问。case2维护dfs序,对dfs序建可持久化的trie树。这样做的空间复杂度是O(nw),时间复杂度是O(nw).

代码:

1 #include<bits/stdc++.h>
2 using namespace std;
3
4 const int maxn=102000;
5
6 int n,q;
7 int v[maxn];
8 vector<int> g[maxn];
9
10 vector<pair<int,int> > qy[maxn];
11 vector<pair<int,int> > vec;
12
13 int ans[maxn],num,kd[maxn];
14 int dep[maxn],dfsin[maxn],dfsout[maxn],fa[maxn];
15
16 vector<pair<int,int> > Lca[maxn];
17 int pre[maxn];
18
19 int found(int x){
20     int rx = x; while(pre[rx] != rx) rx = pre[rx];
21     while(pre[x] != rx){
22     int t = pre[x]; pre[x] = rx; x = t;
23     }
24     return rx;
25 }
26
27 void dfs(int now,int dp,int f){
28     dfsin[now] = dfsout[now] = ++num;fa[now] = f; dep[now] = dp;
29     for(auto pr:Lca[now]){
30     if(dep[pr.first] == 0) continue;
31     int la = found(pr.first);
32     qy[now].push_back(make_pair(la,pr.second));
33     qy[pr.first].push_back(make_pair(la,pr.second));
34     }
35     for(auto i:g[now]){
36     if(i == f) continue;
37     dfs(i,dp+1,now);
38     dfsout[now] = dfsout[i];
39     }
40     pre[found(now)] = found(f);
41 }
42
43 void read(){
44     scanf("%d%d",&n,&q);
45     for(int i=1;i<=n;i++) scanf("%d",&v[i]);
46     for(int i=1;i<n;i++){
47     int x,y; scanf("%d%d",&x,&y);
48     g[x].push_back(y); g[y].push_back(x);
49     }
50     for(int i=1;i<=q;i++){
51     int cas; scanf("%d",&cas);
52     if(cas == 1){
53         int x,y; scanf("%d%d",&x,&y);
54         vec.push_back(make_pair(x,i));kd[i] = y;
55     }else{
56         int x,y,z; scanf("%d%d%d",&x,&y,&z);
57         Lca[x].push_back(make_pair(y,i));
58         if(x!=y) Lca[y].push_back(make_pair(x,i));
59         kd[i] = z;
60     }
61     }
62     for(int i=1;i<=n;i++) pre[i] = i;
63     dfs(1,1,0);
64 }
65
66 int his[maxn],om;
67 int sz[maxn*130],ch[maxn*130][2];
68
69 void follow(int pt,int last,int dt){
70     int hbit = 30;
71     while(hbit!=-1){
72     if((1<<hbit)&dt){
73         ch[pt][0] = ch[last][0];
74         ch[pt][1] = ++num;
75         pt = num; last = ch[last][1];
76         sz[pt] = sz[last]+1;
77     }else{
78         ch[pt][1] = ch[last][1];
79         ch[pt][0] = ++num;
80         pt = num; last = ch[last][0];
81         sz[pt] = sz[last]+1;
82     }
83     hbit--;
84     }
85 }
86
87 void ins(int now){
88     int last = his[om-1];
89     num++;int pt = num; sz[pt] = sz[last]+1;
90     his[om] = num;
91     follow(pt,last,v[now]);
92 }
93
94 int query(int now,int last,int z){
95     now = his[now]; last = his[last];
96     int hbit = 30;
97     while(hbit!=-1){
98     if((1<<hbit)&z){
99         if(sz[ch[now][0]]-sz[ch[last][0]]){
100         now = ch[now][0];last = ch[last][0];
101         }else{
102         z -= (1<<hbit);now = ch[now][1];last = ch[last][1];
103         }
104     }else{
105         if(sz[ch[now][1]]-sz[ch[last][1]]){
106         z += (1<<hbit);
107         now = ch[now][1];last = ch[last][1];
108         }else{
109         now = ch[now][0];last = ch[last][0];
110         }
111     }
112     hbit--;
113     }
114     return z;
115 }
116
117 void del(int now){his[om] = 0;}
118
119 void dfs2(int now){
120     om++;ins(now);
121     for(auto pr:qy[now]){
122     int last = dep[pr.first]-1,data = kd[pr.second];
123     ans[pr.second] = max(ans[pr.second],query(dep[now],last,data));
124     }
125     for(auto i:g[now]){
126     if(i == fa[now]) continue;
127     dfs2(i);
128     }
129     del(now);om--;
130 }
131
132 void dfs3(int now){
133     om++;ins(now);
134     for(auto i:g[now]){
135     if(i == fa[now]) continue;
136     dfs3(i);
137     }
138 }
139
140 void work(){
141     num = 1;his[0] = 1;
142     dfs2(1);
143     memset(ch,0,sizeof(ch));memset(sz,0,sizeof(sz));
144     num = 1;his[0] = 1;om = 0;
145     dfs3(1);
146     for(auto pr:vec){
147     int st = dfsin[pr.first],ed = dfsout[pr.first];
148     ans[pr.second] = query(ed,st-1,kd[pr.second]);
149     }
150     for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
151 }
152
153 int main(){
154     read();
155     work();
156     return 0;
157 }

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: