Nhảy chuyển đến

Từ điển thụ (Trie)

Định nghĩa

Từ điển thụ, tiếng Anh danh trie. Xem tên đoán nghĩa, chính là một cái giống từ điển giống nhau thụ.

Dẫn vào

Trước phóng một trương đồ:

trie1

Có thể phát hiện, này cây từ điển thụ dùng biên tới đại biểu chữ cái, mà từ căn giao điểm đến trên cây mỗ một giao điểm đường nhỏ liền đại biểu một chữ phù xuyến. Cử cái ví dụ,Tỏ vẻ chính là tự phù xuyếncaa.

trie kết cấu phi thường hảo hiểu, chúng ta dùngTỏ vẻ giao điểmTự phù chỉ hướng tiếp theo cái giao điểm, hoặc nói là giao điểmĐại biểu tự phù xuyến mặt sau tăng thêm một chữ phùHình thành tự phù xuyến giao điểm. (Lấy giá trị phạm vi cùng tự phù tập lớn nhỏ có quan hệ, không nhất định là.)

Có khi yêu cầu đánh dấu cắm vào tiến trie chính là này đó tự phù xuyến, mỗi lần cắm vào hoàn thành khi ở cái này tự phù xuyến sở đại biểu tiết điểm chỗ đánh thượng đánh dấu là được.

Thực hiện

Phóng một cái kết cấu thể phong trang khuôn mẫu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
structtrie{
intnex[100000][26],cnt;
boolexist[100000];// nên giao điểm kết cục tự phù xuyến hay không tồn tại

voidinsert(char*s,intl){// cắm vào tự phù xuyến
intp=0;
for(inti=0;il;i++){
intc=s[i]-'a';
if(!nex[p][c])nex[p][c]=++cnt;// nếu không có, liền tăng thêm giao điểm
p=nex[p][c];
}
exist[p]=true;
}

boolfind(char*s,intl){// tra tìm tự phù xuyến
intp=0;
for(inti=0;il;i++){
intc=s[i]-'a';
if(!nex[p][c])return0;
p=nex[p][c];
}
returnexist[p];
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
classtrie:
def__init__(self):
self.nex=[[0foriinrange(26)]forjinrange(100000)]
self.cnt=0
self.exist=[False]*100000# nên giao điểm kết cục tự phù xuyến hay không tồn tại

definsert(self,s):# cắm vào tự phù xuyến
p=0
foriins:
c=ord(i)-ord("a")
ifnotself.nex[p][c]:
self.cnt+=1
self.nex[p][c]=self.cnt# nếu không có, liền tăng thêm giao điểm
p=self.nex[p][c]
self.exist[p]=True

deffind(self,s):# tra tìm tự phù xuyến
p=0
foriins:
c=ord(i)-ord("a")
ifnotself.nex[p][c]:
returnFalse
p=self.nex[p][c]
returnself.exist[p]

Ứng dụng

Kiểm tra tự phù xuyến

Từ điển thụ nhất cơ sở ứng dụng —— tra tìm một chữ phù xuyến hay không ở “Từ điển” trung xuất hiện quá.

Vì thế hắn sai lầm điểm danh bắt đầu rồi

Cho ngươiCái tên xuyến, sau đó tiến hànhThứ điểm danh, mỗi lần ngươi yêu cầu trả lời “Tên không tồn tại”, “Lần đầu tiên điểm đến tên này”, “Đã điểm quá tên này” chi nhất.

,,Sở hữu tự phù xuyến chiều dài không vượt qua.

Lời giải trong đề bài

Đối sở hữu tên kiến trie, lại ở trie trung tuần tra tự phù xuyến hay không tồn tại, hay không đã điểm quá danh, lần đầu tiên điểm danh khi đánh dấu vì điểm quá danh.

Tham khảo số hiệu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include&LTcstdio>
usingnamespacestd;
constexprintN=500010;

chars[N];
intn,m,ch[N][26],tag[N],tot=1;

intmain(){
scanf("%d",&n);

for(inti=1;in;++i){
scanf("%s",s+1);
intu=1;
for(intj=1;s[j];++j){
intc=s[j]-'a';
// nếu cái này tiết điểm tử tiết điểm trúng không có cái này tự phù, tăng thêm thượng cũng đem nên tự phù tiết dấu chấm câu ký lục vì ++tot
if(!ch[u][c])ch[u][c]=++tot;
u=ch[u][c];// hướng càng sâu một tầng tìm tòi
}
tag[u]=1;// cuối cùng một chữ phù vì tiết điểm u tên chưa bị phỏng vấn đến ký lục vì 1
}

scanf("%d",&m);

while(m--){
scanf("%s",s+1);
intu=1;
for(intj=1;s[j];++j){
intc=s[j]-'a';
u=ch[u][c];
if(!u)break;// không tồn tại đối ứng tự phù ra biên thuyết minh tên không tồn tại
}
if(tag[u]==1){
tag[u]=2;// cuối cùng một chữ phù vì tiết điểm u tên đã bị phỏng vấn
puts("OK");
}elseif(tag[u]==2)// đã bị phỏng vấn, lặp lại phỏng vấn
puts("REPEAT");
else
puts("WRONG");
}

return0;
}

AC tự động cơ

trie làAC tự động cơMột bộ phận.

Giữ gìn dị hoặc cực trị

Đem số cơ số hai tỏ vẻ cho rằng một chữ phù xuyến, liền có thể kiến ra tự phù tập vìtrie thụ.

BZOJ1954 dài nhất dị hoặc đường nhỏ

Cho ngươi một cây mang biên quyền thụ, cầuKhiến choĐếnĐường nhỏ thượng biên quyền dị hoặc cùng lớn nhất, phát ra cái này cực đại. Nơi này dị hoặc cùng chỉ chính là sở hữu biên quyền dị hoặc.

Điểm số không vượt qua,Biên quyền ởNội.

Lời giải trong đề bài

Tùy tiện chỉ định một cái căn,DùngTỏ vẻCùngChi gian đường nhỏ biên quyền dị hoặc cùng, như vậy,Bởi vìLCATrở lên bộ phận dị hoặc hai lần triệt tiêu.

Như vậy, nếu đem sở hữuCắm vào đến một cây trie trung, liền có thể đối mỗi cáiNhanh chóng cầu ra cùng nó dị hoặc cùng lớn nhất:

Từ trie căn bắt đầu, nếu có thể hướng cùngTrước mặt vị bất đồng tử thụ đi, liền hướng bên kia đi, nếu không không có lựa chọn.

Lòng tham chính xác tính: Nếu như vậy đi, này một vị vì;Nếu không như vậy đi, này một vị liền sẽ vì.Mà địa vị cao là yêu cầu ưu tiên tận lực đại.

Tham khảo số hiệu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include&LTalgorithm>
#include&LTiostream>
usingnamespacestd;

constexprintN=100010;

inthead[N],nxt[N1],to[N1],weight[N1],cnt;
intn,dis[N],ch[N5][2],tot=1,ans;

voidinsert(intx){
for(inti=30,u=1;i>=0;--i){
intc=((x>>i)&1);// cơ số hai một vị một vị xuống phía dưới lấy
if(!ch[u][c])ch[u][c]=++tot;
u=ch[u][c];
}
}

voidget(intx){
intres=0;
for(inti=30,u=1;i>=0;--i){
intc=((x>>i)&1);
if(ch[u][c^1]){// nếu có thể hướng cùng trước mặt vị bất đồng tử thụ đi, liền hướng bên kia đi
u=ch[u][c^1];
res|=(1i);
}else
u=ch[u][c];
}
ans=max(ans,res);// đổi mới đáp án
}

voidadd(intu,intv,intw){// kiến biên
nxt[++cnt]=head[u];
head[u]=cnt;
to[cnt]=v;
weight[cnt]=w;
}

voiddfs(intu,intfa){
insert(dis[u]);
get(dis[u]);
for(inti=head[u];i;i=nxt[i]){// biến lịch tử tiết điểm
intv=to[i];
if(v==fa)continue;
dis[v]=dis[u]^weight[i];
dfs(v,u);
}
}

intmain(){
cin.tie(nullptr)->sync_with_stdio(false);
cin>>n;

for(inti=1;in;++i){
intu,v,w;
cin>>u>>v>>w;
add(u,v,w);// song hướng biên
add(v,u,w);
}

dfs(1,0);

coutans;
return0;
}

Giữ gìn dị hoặc cùng

01-trie là chỉ tự phù tập vìtrie. 01-trie có thể dùng để giữ gìn một ít con số dị hoặc cùng, duy trì sửa chữa ( xóa bỏ + một lần nữa cắm vào ), cùng toàn cục thêm một ( tức: Làm này sở giữ gìn sở hữu trị số tăng lên1,Bản chất là một loại đặc thù sửa chữa thao tác ).

Nếu muốn giữ gìn dị hoặc cùng, yêu cầu ấn giá trị từ thấp vị đến địa vị cao thành lập trie.

Một cái ước định:Văn trung nói trước mặt tiết điểmHướng lên trênChỉ trước mặt tiết điểm đến căn con đường này, trước mặt tiết điểmĐi xuốngChỉ trước mặt giao điểm tử thụ.

Cắm vào & xóa bỏ

Nếu muốn giữ gìn dị hoặc cùng, chúng taChỉ cầnBiết mỗ một vị thượng0Cùng1Cái sốChẵn lẻ tínhCó thể, cũng chính là đối với con số1Tới nói, đương thả chỉ đương này một vị thượng con số1Cái số vì số lẻ khi, này một vị thượng con số mới là1,Thỉnh thời khắc nhớ kỹ này đoạn văn tự: Nếu chỉ là giữ gìn dị hoặc cùng, chúng ta chỉ cần biết mỗ một vị thượng1Số lượng có thể, không cần phải biết rằng trie rốt cuộc giữ gìn này đó con số.

Đối với mỗi một cái tiết điểm, chúng ta yêu cầu ký lục dưới ba cái lượng:

  • ch[o][0/1]Đốt ngón tay điểmoHai cái nhi tử,ch[o][0]Chỉ tiếp theo vị là0,Cùng lých[o][1]Chỉ tiếp theo vị là1.
  • w[o]Đốt ngón tay điểmoĐến này phụ thân tiết điểm này bên cạnh trị số số lượng ( quyền giá trị ). Mỗi cắm vào một con sốx,xCơ số hai tách ra sau ở trie thượng đường nhỏ quyền giá trị đều sẽ+1.
  • xorv[o]Chỉ lấyoLàm gốc tử thụ giữ gìn dị hoặc cùng.

Cụ thể giữ gìn giao điểm số hiệu như sau sở kỳ.

1
2
3
4
5
6
7
8
9
10
11
12
13
voidmaintain(into){
w[o]=xorv[o]=0;
if(ch[o][0]){
w[o]+=w[ch[o][0]];
xorv[o]^=xorv[ch[o][0]]1;
}
if(ch[o][1]){
w[o]+=w[ch[o][1]];
xorv[o]^=(xorv[ch[o][1]]1)|(w[ch[o][1]]&1);
}
// w[o] = w[o] & 1;
// chỉ cần biết chẵn lẻ tính có thể, không cần cụ thể giá trị. Đương nhiên những lời này xóa rớt cũng có thể, bởi vì câu trên cũng chỉ lợi dụng hắn chẵn lẻ tính.
}

Cắm vào cùng xóa bỏ số hiệu phi thường tương tự.

Yêu cầu chú ý địa phương chính là:

  • Nơi nàyMAXHChỉ trie chiều sâu, cũng chính là cưỡng chế làm mỗi một cái lá cây tiết điểm đến căn khoảng cách vìMAXH.Đối với một ít tương đối tiểu nhân giá trị, khả năng có đôi khi không cần thành lập sâu như vậy ( tỷ như: Nếu cắm vào con số4,Phân giải thành cơ số hai sau vì100,Từ căn bắt đầu cắm vào001Này ba vị có thể ), nhưng là chúng ta cưỡng chế cắm vàoMAXHVị. Làm như vậy mục đích là vì dễ bề toàn cục+1Khi xử lý tiến vị. Tỷ như: Nếu nguyên con số là3(11), tăng lên lúc sau biến thành4(100), nếu lúc trước cắm vào3Khi chỉ cắm vào2Vị, kia nơi này tiến vị liền không có.

  • Cắm vào cùng xóa bỏ, chỉ cần sửa chữa lá cây tiết điểmw[]Có thể, ở hồi tưởng trong quá trình một đường giữ gìn là được.

Thực hiện
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
namespacetrie{
constexprintMAXH=21;
intch[_*(MAXH+1)][2],w[_*(MAXH+1)],xorv[_*(MAXH+1)];
inttot=0;

intmknode(){
++tot;
ch[tot][1]=ch[tot][0]=w[tot]=xorv[tot]=0;
returntot;
}

voidmaintain(into){
w[o]=xorv[o]=0;
if(ch[o][0]){
w[o]+=w[ch[o][0]];
xorv[o]^=xorv[ch[o][0]]1;
}
if(ch[o][1]){
w[o]+=w[ch[o][1]];
xorv[o]^=(xorv[ch[o][1]]1)|(w[ch[o][1]]&1);
}
w[o]=w[o]&1;
}

voidinsert(int&o,intx,intdp){
if(!o)o=mknode();
if(dp>MAXH)return(void)(w[o]++);
insert(ch[o][x&1],x>>1,dp+1);
maintain(o);
}

voiderase(into,intx,intdp){
if(dp>20)return(void)(w[o]--);
erase(ch[o][x&1],x>>1,dp+1);
maintain(o);
}
}// namespace trie

Toàn cục thêm một

Cái gọi là toàn cục thêm một chính là chỉ, làm này cây trie trung sở hữu trị số+1.

Hình thức hóa giảng, thiết trie trung giữ gìn trị số có,Toàn cục thêm một sau trong đó giữ gìn giá trị hẳn là biến thành

1
2
3
4
5
voidaddall(into){
swap(ch[o][0],ch[o][1]);
if(ch[o][0])addall(ch[o][0]);
maintain(o);
}
Quá trình

Chúng ta tự hỏi một chút cơ số hai ý nghĩa hạ+1Là như thế nào thao tác.

Chúng ta chỉ cần từ thấp vị đến địa vị cao bắt đầu tìm cái thứ nhất xuất hiện0,Đem nó biến thành1,Sau đó vị trí này mặt sau1Đều biến thành0Là được.

Phía dưới cấp ra mấy cái ví dụ cảm thụ một chút: ( dấu móc nội con số tỏ vẻ này đối ứng số thập phân con số )

1
2
3
4
5
1000(8) + 1 = 1001(9);
10011(19) + 1 = 10100(20);
11111(31) + 1 = 100000(32);
10101(21) + 1 = 10110(22);
100000000111111(16447) + 1 = 100000001000000(16448);

Đối ứng trie thao tác, kỳ thật chính là trao đổi này tả hữu nhi tử, theoTrao đổi sau0Biên đi xuống đệ quy thao tác là được.

Nhìn lại một chútw[o]Định nghĩa:w[o]Đốt ngón tay điểmoĐến này phụ thân tiết điểm này bên cạnh trị số số lượng ( quyền giá trị ).

Có hay không cảm giác cái này định nghĩa có điểm quái đâu? Nếu ở phụ thân giao điểm tồn trữ đến hai cái nhi tử này biên biên quyền có lẽ sẽ càng tiếp cận với thói quen. Nhưng là ở chỗ này, ở trao đổi tả hữu nhi tử thời điểm, ở nhi tử giao điểm tồn trữ đến phụ thân này biên khoảng cách, hiển nhiên càng thêm phương tiện.

01-trie xác nhập

Chỉ chính là đem kể trên hai cái 01-trie tiến hành xác nhập, đồng thời xác nhập giữ gìn tin tức.

Khả năng về xác nhập trie văn chương tương đối thiếu, kỳ thật xác nhập trie hòa hợp cũng đoạn thẳng thụ ý nghĩ phi thường tương tự, có thể tìm tòi “Xác nhập đoạn thẳng thụ” tới học tập như thế nào xác nhập trie.

Kỳ thật xác nhập trie phi thường đơn giản, chính là suy xét một chút chúng ta có một cáiint merge(int a, int b)Hàm số, cái này hàm số truyền vào hai cái trie thụ ở vào cùng tương đối vị trí giao điểm đánh số, sau đó xác nhập hoàn thành sau phản hồi xác nhập hoàn thành giao điểm đánh số.

Quá trình

Suy xét như thế nào thực hiện?

Phân ba loại tình huống:

  • NếuaKhông có vị trí này thượng giao điểm, tân xác nhập giao điểm chính làb
  • NếubKhông có vị trí này thượng giao điểm, tân xác nhập giao điểm chính làa
  • Nếua,bĐều tồn tại, vậy đembTin tức xác nhập đếnaThượng, tân xác nhập giao điểm chính làa,Sau đó đệ quy thao tác xử lý a tả hữu nhi tử.

    Nhắc nhở:Nếu yêu cầu xác nhập là đem a, b xác nhập đến một cây tân trên cây, nơi này có thể tân kiến giao điểm, sau đó xác nhập đến cái này tân giao điểm thượng, nơi này số hiệu thực hiện gần là đem b tin tức xác nhập đến a thượng.

Thực hiện

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
intmerge(inta,intb){
if(!a)returnb;// nếu a không có vị trí này thượng giao điểm, phản hồi b
if(!b)returna;// nếu b không có vị trí này thượng giao điểm, phản hồi a
/*
Nếu `a`, `b` đều tồn tại,
Vậy đem `b` tin tức xác nhập đến `a` thượng.
*/
w[a]=w[a]+w[b];
xorv[a]^=xorv[b];
/* không cần sử dụng maintain(),
maintain() là xác nhập a hai cái nhi tử tin tức
Mà nơi này yêu cầu a b hai cái tiết điểm tiến hành tin tức xác nhập
*/
ch[a][0]=merge(ch[a][0],ch[b][0]);
ch[a][1]=merge(ch[a][1],ch[b][1]);
returna;
}

Kỳ thật trie đều có thể xác nhập, nói cách khác, trie xác nhập không chỉ có giới hạn trong 01-trie.

【luogu-P6018】【Ynoi2010】Fusion tree

Cho ngươi một câyCái giao điểm thụ, mỗi cái giao điểm có quyền giá trị.Thứ thao tác. Yêu cầu duy trì dưới thao tác.

  • Đem trên cây cùng một cái tiết điểmKhoảng cách vìTiết điểm thượng quyền giá trị.Nơi này trên cây hai điểm gian khoảng cách định nghĩa vì từ một chút xuất phát đến mặt khác một chút ngắn nhất đường nhỏ bên trên điều số.
  • Ở một cái tiết điểmThượng quyền giá trị.
  • Dò hỏi trên cây cùng một cái tiết điểmKhoảng cách vìSở hữu tiết điểm thượng quyền giá trị dị hoặc cùng. Đối vớiSố liệu, thỏa mãn,,,,.Bảo đảm tùy ý thời khắc mỗi cái tiết điểm quyền giá trị phi phụ.
Lời giải trong đề bài

Mỗi cái giao điểm thành lập một cây trie giữ gìn này nhi tử quyền giá trị, trie hẳn là duy trì toàn cục thêm một. Có thể sử dụng ở mỗi một cái giao điểm thượng thiết trí lười đánh dấu tới đánh dấu nhi tử quyền giá trị gia tăng lượng.

Tham khảo số hiệu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include&LTiostream>
usingnamespacestd;
constexprint_=5e5+10;

namespacetrie{
constexprint_n=_*25;
intrt[_];
intch[_n][2];
intw[_n];//`w[o]` đốt ngón tay điểm `o` đến này phụ thân tiết điểm này bên cạnh trị số số lượng ( quyền giá trị ).
intxorv[_n];
inttot=0;

voidmaintain(into){// giữ gìn w số tổ cùng xorv ( quyền giá trị dị hoặc ) số tổ
w[o]=xorv[o]=0;
if(ch[o][0]){
w[o]+=w[ch[o][0]];
xorv[o]^=xorv[ch[o][0]]1;
}
if(ch[o][1]){
w[o]+=w[ch[o][1]];
xorv[o]^=(xorv[ch[o][1]]1)|(w[ch[o][1]]&1);
}
}

intmknode(){// sáng tạo một cái tân tiết điểm
++tot;
ch[tot][0]=ch[tot][1]=0;
w[tot]=0;
returntot;
}

voidinsert(int&o,intx,intdp){// x là quyền trọng, dp là chiều sâu
if(!o)o=mknode();
if(dp>20)return(void)(w[o]++);
insert(ch[o][x&1],x>>1,dp+1);
maintain(o);
}

voiderase(into,intx,intdp){
if(dp>20)return(void)(w[o]--);
erase(ch[o][x&1],x>>1,dp+1);
maintain(o);
}

voidaddall(into){// đối sở hữu tiết điểm +1 sắp sở hữu tiết điểm ch[o][1] cùng ch[o][0] trao đổi
swap(ch[o][1],ch[o][0]);
if(ch[o][0])addall(ch[o][0]);
maintain(o);
}
}// namespace trie

inthead[_];

structedges{
intnode;
intnxt;
}edge[_1];

inttot=0;

voidadd(intu,intv){
edge[++tot].nxt=head[u];
head[u]=tot;
edge[tot].node=v;
}

intn,m;
intrt;
intlztar[_];
intfa[_];

voiddfs0(into,intf){// được đến fa số tổ
fa[o]=f;
for(inti=head[o];i;i=edge[i].nxt){// biến lịch tử tiết điểm
intnode=edge[i].node;
if(node==f)continue;
dfs0(node,o);
}
}

intV[_];

// quyền giá trị hàm số
intget(intx){return(fa[x]==-1?0:lztar[fa[x]])+V[x];}

intmain(){
cin>>n>>m;
for(inti=1;in;i++){
intu,v;
cin>>u>>v;
add(u,v);// song hướng kiến biên
add(rt=v,u);
}
dfs0(rt,-1);// rt là tùy cơ một cái điểm
for(inti=1;in;i++){
cin>>V[i];
if(fa[i]!=-1)trie::insert(trie::rt[fa[i]],V[i],0);
}
while(m--){
intopt,x;
cin>>opt>>x;
if(opt==1){
lztar[x]++;
if(x!=rt){
if(fa[fa[x]]!=-1)trie::erase(trie::rt[fa[fa[x]]],get(fa[x]),0);
V[fa[x]]++;
if(fa[fa[x]]!=-1)
trie::insert(trie::rt[fa[fa[x]]],get(fa[x]),0);// một lần nữa cắm vào
}
trie::addall(trie::rt[x]);// đối sở hữu tiết điểm +1
}elseif(opt==2){
intv;
cin>>v;
if(x!=rt)trie::erase(trie::rt[fa[x]],get(x),0);
V[x]-=v;
if(x!=rt)trie::insert(trie::rt[fa[x]],get(x),0);// một lần nữa cắm vào
}else{
intres=0;
res=trie::xorv[trie::rt[x]];
res^=get(fa[x]);
coutres'\n';
}
}
return0;
}
【luogu-P6623】【 tỉnh tuyển liên khảo 2020 A cuốn 】 thụ

Cấp định một câyCái giao điểm có căn thụ,Giao điểm từBắt đầu đánh số, căn giao điểm vìHào giao điểm, mỗi cái giao điểm có một cái chính số nguyên quyền giá trị.ThiếtHào giao điểm tử thụ nội ( bao hàmTự thân ) sở hữu giao điểm đánh số vì,Định nghĩaGiá trị vì:
Trong đó.
Tỏ vẻ trên câyHào giao điểm cùngHào giao điểm gian duy nhất đơn giản đường nhỏ sở bao hàm biên số,.Tỏ vẻ dị hoặc giải toán. Thỉnh ngươi cầu raKết quả.

Lời giải trong đề bài

Suy xét mỗi cái giao điểm đối này sở hữu tổ tiên cống hiến. Mỗi cái giao điểm thành lập trie, mới bắt đầu trước chỉ tồn cái này giao điểm quyền giá trị, sau đó từ đế hướng về phía trước xác nhập mỗi cái nhi tử giao điểm thượng trie, sau đó lại toàn cục thêm một, hoàn thành sau thống kê đáp án.

Tham khảo số hiệu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
constexprint_=526010;
intn;
intV[_];
intdebug=0;

namespacetrie{
constexprintMAXH=21;
intch[_*(MAXH+1)][2],w[_*(MAXH+1)],xorv[_*(MAXH+1)];
inttot=0;

intmknode(){
++tot;
ch[tot][1]=ch[tot][0]=w[tot]=xorv[tot]=0;
returntot;
}

voidmaintain(into){
w[o]=xorv[o]=0;
if(ch[o][0]){
w[o]+=w[ch[o][0]];
xorv[o]^=xorv[ch[o][0]]1;
}
if(ch[o][1]){
w[o]+=w[ch[o][1]];
xorv[o]^=(xorv[ch[o][1]]1)|(w[ch[o][1]]&1);
}
w[o]=w[o]&1;
}

voidinsert(int&o,intx,intdp){
if(!o)o=mknode();
if(dp>MAXH)return(void)(w[o]++);
insert(ch[o][x&1],x>>1,dp+1);
maintain(o);
}

intmerge(inta,intb){
if(!a)returnb;
if(!b)returna;
w[a]=w[a]+w[b];
xorv[a]^=xorv[b];
ch[a][0]=merge(ch[a][0],ch[b][0]);
ch[a][1]=merge(ch[a][1],ch[b][1]);
returna;
}

voidaddall(into){
swap(ch[o][0],ch[o][1]);
if(ch[o][0])addall(ch[o][0]);
maintain(o);
}
}// namespace trie

intrt[_];
longlongAns=0;
vectorint>E[_];

voiddfs0(into){
for(inti=0;iE[o].size();i++){
intnode=E[o][i];
dfs0(node);
rt[o]=trie::merge(rt[o],rt[node]);
}
trie::addall(rt[o]);
trie::insert(rt[o],V[o],0);
Ans+=trie::xorv[rt[o]];
}

intmain(){
n=read();
for(inti=1;in;i++)V[i]=read();
for(inti=2;in;i++)E[read()].push_back(i);
dfs0(1);
printf("%lld",Ans);
return0;
}

Nhưng kéo dài hóa từ điển thụ

Tham kiếnNhưng kéo dài hóa từ điển thụ.