1
/*
2
3
Author: LTL
4
5
Data: 2011-6-8
6
7
*/
8
9
10
11 #include <iostream>
12
13 #include <memory.h>
14
15 #include <cstdio>
16
17 #include <cstdlib>
18
19 #include <algorithm>
20
21 #include <cmath>
22
23
24
25
#define InputFileName "Data.in"
26
27
#define OutputFileName "Data.out"
28
29
#define Max(a, b) (a > b ? a : b)
30
31
32
33
using
namespace std;
34
35
36
37
const
int MaxN =
31000, MaxE = MaxN*
2, oo =
1000000000;
38
39
40
41
int n, m, Next[MaxE], v[MaxE], Head[MaxN], ENum, Total, d[MaxE][
20], Depth[MaxN], Size[MaxN], Heavy[MaxN], Father[MaxN], Pos[MaxN];
42
43
bool View[MaxN];
44
45
int Seq[MaxN], STNum[MaxN], STPos[MaxN], STSize[MaxN], STTail[MaxN], Root[MaxN], STTotal, Left[MaxN*
4], Right[MaxN*
4], f[MaxN*
4][
2][
2], L[MaxN*
4][
2], R[MaxN*
4][
2];
46
47
char a[MaxN][
3];
48
49
50
51 inline
void AddEdge(
const
int x,
const
int y)
52
53 {
54
55 Next[++ENum] = Head[x];
56
57 v[Head[x] = ENum] = y;
58
59 }
60
61
62
63
void Init()
64
65 {
66
67 scanf(
"
%d%d
", &n, &m);
68
69
for (
int i =
1, x, y; i < n; ++i)
70
71 {
72
73 scanf(
"
%d%d
", &x, &y);
74
75 AddEdge(x, y);
76
77 AddEdge(y, x);
78
79 }
80
81
for (
int i =
1; i <= n; ++i)
82
83 scanf(
"
%s
", a[i]);
84
85 }
86
87
88
89
void DFS(
const
int t)
90
91 {
92
93 View[t] = Size[t] =
1;
94
95 d[Pos[t] = ++Total][
0] = t;
96
97
for (
int i = Head[t]; i; i = Next[i])
98
99
if (! View[v[i]])
100
101 {
102
103 Depth[v[i]] = Depth[t]+
1;
104
105 Father[v[i]] = t;
106
107 DFS(v[i]);
108
109 Size[t] += Size[v[i]];
110
111 d[++Total][
0] = t;
112
113
if (! Heavy[t] || Size[v[i]] > Size[Heavy[t]])
114
115 Heavy[t] = v[i];
116
117 }
118
119 }
120
121
122
123 inline
int RMQMin(
const
int x,
const
int y)
124
125 {
126
127
return Depth[x] < Depth[y] ? x : y;
128
129 }
130
131
132
133 inline
int LCA(
int x,
int y)
134
135 {
136
137
if ((x = Pos[x]) > (y = Pos[y]))
138
139 swap(x, y);
140
141
const
int k = (
int)log2(y-x+
1);
142
143
return RMQMin(d[x][k], d[y-(
1 << k)+
1][k]);
144
145 }
146
147
148
149 inline
void Combine(
int c[
2][
2],
int a[
2][
2],
int b[
2][
2])
150
151 {
152
153
int Res[
2][
2];
154
155 Res[
0][
0] = Max(a[
0][
0]+b[
0][
0], a[
0][
1]+b[
1][
0]);
156
157 Res[
0][
1] = Max(a[
0][
0]+b[
0][
1], a[
0][
1]+b[
1][
1]);
158
159 Res[
1][
0] = Max(a[
1][
0]+b[
0][
0], a[
1][
1]+b[
1][
0]);
160
161 Res[
1][
1] = Max(a[
1][
0]+b[
0][
1], a[
1][
1]+b[
1][
1]);
162
163 c[
0][
0] = Max(Res[
0][
0], -oo);
164
165 c[
0][
1] = Max(Res[
0][
1], -oo);
166
167 c[
1][
0] = Max(Res[
1][
0], -oo);
168
169 c[
1][
1] = Max(Res[
1][
1], -oo);
170
171 }
172
173
174
175 inline
void CalcL(
int c[
2],
int s[
2][
2],
int a[
2],
int b[
2])
176
177 {
178
179
int r[
2];
180
181 r[
0] = Max(s[
0][
0]+b[
0], s[
0][
1]+b[
1]);
182
183 r[
1] = Max(s[
1][
1]+b[
1], s[
1][
0]+b[
0]);
184
185 c[
0] = Max(r[
0], a[
0]);
186
187 c[
1] = Max(r[
1], a[
1]);
188
189 }
190
191
192
193 inline
void CalcR(
int c[
2],
int s[
2][
2],
int a[
2],
int b[
2])
194
195 {
196
197
int r[
2];
198
199 r[
0] = Max(a[
0]+s[
0][
0], a[
1]+s[
1][
0]);
200
201 r[
1] = Max(a[
1]+s[
1][
1], a[
0]+s[
0][
1]);
202
203 c[
0] = Max(r[
0], b[
0]);
204
205 c[
1] = Max(r[
1], b[
1]);
206
207 }
208
209
210
211
void Build(
int &t,
const
int l,
const
int r)
212
213 {
214
215 t = ++Total;
216
217
if (l == r)
218
219 {
220
221 f[t][
0][
0] = a[Seq[l]][
0] ==
'
.
' ?
1 : -oo;
222
223 f[t][
0][
1] = f[t][
1][
0] = a[Seq[l]][
0] ==
'
.
' && a[Seq[l]][
1] ==
'
.
' ?
2 : -oo;
224
225 f[t][
1][
1] = a[Seq[l]][
1] ==
'
.
' ?
1 : -oo;
226
227 L[t][
0] = Max(f[t][
0][
0], f[t][
0][
1]);
228
229 L[t][
1] = Max(f[t][
1][
0], f[t][
1][
1]);
230
231 L[t][
0] = Max(L[t][
0],
0);
232
233 L[t][
1] = Max(L[t][
1],
0);
234
235 memcpy(R[t], L[t],
sizeof(L[t]));
236
237
return;
238
239 }
240
241
const
int mid = l+r >>
1;
242
243 Build(Left[t], l, mid);
244
245 Build(Right[t], mid+
1, r);
246
247 Combine(f[t], f[Left[t]], f[Right[t]]);
248
249 CalcL(L[t], f[Left[t]], L[Left[t]], L[Right[t]]);
250
251 CalcR(R[t], f[Right[t]], R[Left[t]], R[Right[t]]);
252
253 }
254
255
256
257
void Modify(
const
int t,
const
int l,
const
int r,
const
int p,
const
int k)
258
259 {
260
261
if (l == r)
262
263 {
264
265 f[t][
0][
0] = a[k][
0] ==
'
.
' ?
1 : -oo;
266
267 f[t][
0][
1] = f[t][
1][
0] = a[k][
0] ==
'
.
' && a[k][
1] ==
'
.
' ?
2 : -oo;
268
269 f[t][
1][
1] = a[k][
1] ==
'
.
' ?
1 : -oo;
270
271 L[t][
0] = Max(f[t][
0][
0], f[t][
0][
1]);
272
273 L[t][
1] = Max(f[t][
1][
0], f[t][
1][
1]);
274
275 L[t][
0] = Max(L[t][
0],
0);
276
277 L[t][
1] = Max(L[t][
1],
0);
278
279 memcpy(R[t], L[t],
sizeof(L[t]));
280
281
return;
282
283 }
284
285
const
int mid = l+r >>
1;
286
287
if (p <= mid)
288
289 Modify(Left[t], l, mid, p, k);
290
291
else
292
293 Modify(Right[t], mid+
1, r, p, k);
294
295 Combine(f[t], f[Left[t]], f[Right[t]]);
296
297 CalcL(L[t], f[Left[t]], L[Left[t]], L[Right[t]]);
298
299 CalcR(R[t], f[Right[t]], R[Left[t]], R[Right[t]]);
300
301 }
302
303
304
305
void Query(
const
int t,
const
int l,
const
int r,
const
int x,
const
int y,
int Res[
2][
2],
int rL[
2],
int rR[
2])
306
307 {
308
309
if (x <= l && y >= r)
310
311 {
312
313 memcpy(Res, f[t],
sizeof(f[t]));
314
315 memcpy(rL, L[t],
sizeof(L[t]));
316
317 memcpy(rR, R[t],
sizeof(R[t]));
318
319
return;
320
321 }
322
323
const
int mid = l+r >>
1;
324
325
int tmp[
2][
2], tmpL[
2], tmpR[
2];
326
327
if (x <= mid)
328
329 Query(Left[t], l, mid, x, y, Res, rL, rR);
330
331
if (y > mid)
332
333 Query(Right[t], mid+
1, r, x, y, tmp, tmpL, tmpR);
334
335
if (x <= mid && y > mid)
336
337 {
338
339 CalcL(rL, Res, rL, tmpL);
340
341 CalcR(rR, tmp, rR, tmpR);
342
343 Combine(Res, Res, tmp);
344
345 }
346
347
else
if (y > mid)
348
349 {
350
351 memcpy(Res, tmp,
sizeof(tmp));
352
353 memcpy(rL, tmpL,
sizeof(tmpL));
354
355 memcpy(rR, tmpR,
sizeof(tmpR));
356
357 }
358
359 }
360
361
362
363
void Prework()
364
365 {
366
367 DFS(
1);
368
369
for (
int i, j =
1, k = (
int)log2(Total); j <= k; ++j)
370
371
for (i =
1; i+(
1 << j)-
1 <= Total; ++i)
372
373 d[i][j] = RMQMin(d[i][j-
1], d[i+(
1 << j-
1)][j-
1]);
374
375 Total =
0;
376
377 memset(View,
0,
sizeof(View));
378
379
for (
int i =
1, j; i <= n; ++i)
380
381
if (! View[i])
382
383 {
384
385
for (j = i; Heavy[j]; j = Heavy[j]);
386
387 ++STTotal;
388
389
for (View[j] =
1; Heavy[Father[j]] == j; View[j = Father[j]] =
1)
390
391 Seq[STPos[j] = ++STSize[STNum[j] = STTotal]] = j;
392
393 Seq[STPos[STTail[STTotal] = j] = ++STSize[STNum[j] = STTotal]] = j;
394
395 Build(Root[STTotal],
1, STSize[STTotal]);
396
397 }
398
399 }
400
401
402
403
void Ask1(
int x,
const
int y,
int Res[
2][
2],
int rL[
2],
int rR[
2])
404
405 {
406
407
if (STNum[x] == STNum[y])
408
409 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STPos[y], Res, rL, rR);
410
411
else
412
413 {
414
415
int tmpL[
2], tmpR[
2], tmp[
2][
2];
416
417 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STSize[STNum[x]], Res, rL, rR);
418
419 x = Father[STTail[STNum[x]]];
420
421
for (; STNum[x] != STNum[y]; x = Father[STTail[STNum[x]]])
422
423 {
424
425 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STSize[STNum[x]], tmp, tmpL, tmpR);
426
427 CalcL(rL, Res, rL, tmpL);
428
429 CalcR(rR, tmp, rR, tmpR);
430
431 Combine(Res, Res, tmp);
432
433 }
434
435 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STPos[y], tmp, tmpL, tmpR);
436
437 CalcL(rL, Res, rL, tmpL);
438
439 CalcR(rR, tmp, rR, tmpR);
440
441 Combine(Res, Res, tmp);
442
443 }
444
445 }
446
447
448
449
void Ask2(
int x,
const
int y,
int Res[
2][
2],
int rL[
2],
int rR[
2])
450
451 {
452
453
if (STNum[x] == STNum[y])
454
455 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STPos[y]-
1, Res, rL, rR);
456
457
else
458
459 {
460
461
int tmpL[
2], tmpR[
2], tmp[
2][
2];
462
463 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STSize[STNum[x]], Res, rL, rR);
464
465 x = Father[STTail[STNum[x]]];
466
467
for (; STNum[x] != STNum[y]; x = Father[STTail[STNum[x]]])
468
469 {
470
471 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STSize[STNum[x]], tmp, tmpL, tmpR);
472
473 CalcL(rL, Res, rL, tmpL);
474
475 CalcR(rR, tmp, rR, tmpR);
476
477 Combine(Res, Res, tmp);
478
479 }
480
481
if (STPos[y] > STPos[x])
482
483 {
484
485 Query(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], STPos[y]-
1, tmp, tmpL, tmpR);
486
487 CalcL(rL, Res, rL, tmpL);
488
489 CalcR(rR, tmp, rR, tmpR);
490
491 Combine(Res, Res, tmp);
492
493 }
494
495 }
496
497 }
498
499
500
501
int main()
502
503 {
504
505 #ifndef ONLINE_JUDGE
506
507 freopen(InputFileName,
"
r
", stdin);
508
509 freopen(OutputFileName,
"
w
", stdout);
510
511
#endif
512
513 Init();
514
515 Prework();
516
517
char cmd[
2];
518
519
for (
int x, y, lca, tmp[
2][
2], Res[
2][
2], Ans, rL[
2], rR[
2], tmpL[
2], tmpR[
2]; m; --m)
520
521 {
522
523 scanf(
"
%s%d
", cmd, &x);
524
525
if (cmd[
0] ==
'
C
')
526
527 {
528
529 scanf(
"
%s
", a[x]);
530
531 Modify(Root[STNum[x]],
1, STSize[STNum[x]], STPos[x], x);
532
533 }
534
535
else
536
537 {
538
539 scanf(
"
%d
", &y);
540
541 lca = LCA(x, y);
542
543 Ask1(x, lca, Res, rL, rR);
544
545
if (y != lca)
546
547 {
548
549 Ask2(y, lca, tmp, tmpR, tmpL);
550
551 swap(tmp[
0][
1], tmp[
1][
0]);
552
553 CalcL(rL, Res, rL, tmpL);
554
555 CalcR(rR, tmp, rR, tmpR);
556
557 Combine(Res, Res, tmp);
558
559 }
560
561 Ans = Max(rL[
0], rL[
1]);
562
563 printf(
"
%d\n
", Ans);
564
565 }
566
567 }
568
569
return
0;
570
571 }
572
573