-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy patharbfind.cpp
102 lines (92 loc) · 2.14 KB
/
arbfind.cpp
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
# include <bits/stdc++.h>
# define NR 80000
# define N 20
using namespace std;
vector <int> v1[NR], v2[NR];
struct elem {
int nr1, nr2, i;
}var[4*NR];
int i,j,n,m,VV,x,l,IND,L,AUX;
int start[4*NR], lg[4*NR], suma[4*NR], ap[NR], Z[4*NR];
int P[4*NR];
int mask=(1<<8)-1;
void citire () {
scanf ("%d", &n);
for (i=1; i<=n; ++i) {
scanf ("%d", &l);
for (j=1; j<=l; ++j) {
scanf ("%d", &x);
v1[i].push_back(x);
}
}
scanf ("%d", &m);
for (i=1; i<=m; ++i) {
scanf ("%d", &l);
for (j=1; j<=l; ++j) {
scanf ("%d", &x);
v2[i].push_back(x);
}
}
}
void make_euler1 (int k, int tata) {
P[++VV]=1;
for (auto &x: v1[k])
if (x!=tata) {
P[++VV]=2;
make_euler1 (x, k);
P[++VV]=3;
}
}
void make_euler2 (int k, int tata) {
P[++VV]=1; start[k]=VV;
for (auto &x: v2[k])
if (x!=tata) {
P[++VV]=2;
make_euler2 (x, k);
P[++VV]=3;
}
}
void Z_algorithm() {
int L=0, R=0;
for (int i=2; i<=VV; ++i) {
if (R<i) { //un Z-Box nou
L=R=i;
while (R<=VV && P[R-i+1]==P[R])
++R;
--R; Z[i]=R-i+1;
} else { //este intr-un Z-Box
int k=i - L + 1;
if (i + Z[k] - 1 < R) Z[i]=Z[k];
else {
L=i; ++R;
while (R<=VV && P[R-i+1]==P[R])
++R;
--R; Z[i]=R-i+1;
}
}
}
}
int main ()
{
freopen ("arbfind.in", "r", stdin);
freopen ("arbfind.out", "w", stdout);
citire ();
make_euler1 (1, 0); //arborele 1
P[++VV]='$';
make_euler2 (1, 0); //arborele 2
Z_algorithm ();
/*for (i=1; i<=VV; ++i)
printf ("%d ", P[i]);
printf ("\n");
for (i=1; i<=VV; ++i)
printf ("%d ", Z[i]);
printf ("\n");*/
//fac sumele partiale
for (i=1; i<=VV; ++i) {
suma[i]=suma[i-1];
if (P[i]==1) ++suma[i];
}
for (i=1; i<=m; ++i)
printf ("%d\n", suma[start[i] + Z[start[i]] - 1] - suma[start[i]-1]);
return 0;
}