View difference between Paste ID: FZnjHPsT and 1amnAc8r
SHOW: | | - or go back to the newest paste.
1
# include <iostream>
2
# include <fstream>
3
# include <sstream>
4
# include <algorithm>
5
# include <numeric>
6
# include <cstdio>
7
# include <cmath>
8
# include <cstdlib>
9
# include <cstring>
10
# include <vector>
11
# include <list>
12
# include <set>
13
# include <map>
14
# include <iomanip>
15
# include <stack>
16
# include <queue>
17
# include <cctype>
18
# include <climits>
19
# include <assert.h>
20
21
using namespace std;
22
23
//conversion
24
//------------------------------------------
25
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
26
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
27
28
typedef long long LL;
29
typedef unsigned long long ULL;
30
typedef vector<int> VI;
31
typedef vector<VI> VVI;
32
typedef vector<LL> VLL;
33
typedef pair<int,int> PII;
34
typedef pair<int, PII> TIII;
35
typedef vector<PII> VPII;
36
typedef vector<double> VD;
37
typedef pair<double,double> PDD;
38
39
const int inf=1000000000;
40
const LL INF=LL(inf)*inf;
41
const double eps=1e-9;
42
const double PI=2*acos(0.0);
43
44
#define GI ({int t;scanf("%d",&t);t;})
45
#define REP(i,a,b) for(int i=a;i<b;i++)
46
#define foreach(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
47
#define ALL(v) (v).begin(),(v).end()
48
#define RALL(a) (a).rbegin(), (a).rend()
49
#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)
50
#define bit(n) (1<<(n))
51
#define bit64(n) ((LL(1))<<(n))
52
#define PB push_back
53
#define SZ size()
54
#define MP make_pair
55
#define CL clear()
56
#define fill(ar,val) memset((ar),(val), sizeof(ar))
57
#define MIN(a,b) {if((a)>(b)) (b);}
58
#define MAX(a,b) {if((a)<(b)) (b);}
59
#define EXIST(s,e) ((s).find(e)!=(s).end())
60
#define SORT(c) sort((c).begin(),(c).end())
61
#define MT(a,b,c) MP(a, MP(b, c))
62
#define sqr(x) ((x)*(x))
63
#define X first
64
#define Y second
65
#define REP(i,a,b) for(int i=a;i<b;i++)
66
#define GI ({int t;scanf("%d",&t);t;})
67
#define DBPRINT cout << "HERE" << debugptr++
68
int debugptr = 0;
69
70
//clock_t start=clock();
71
//fprintf(stderr,"time=%.3lfsec\n",0.001*(clock()-start));
72
73
#define MAXN 10003
74
#define MAXLN 14
75
#define root 1
76
77
int ptr;
78-
int par[MAXN][MAXLN];
78+
int par[MAXN];
79
int chainNo;
80
81
VI adj_list[MAXN];
82
VI costs[MAXN];
83
VI indexx[MAXN];
84
int L[MAXN];
85
int baseArray[MAXN];
86
int posInBase[MAXN];
87
int other_end[MAXN];
88
int subsize[MAXN];
89
int chain[MAXN];
90
int head_of_chain[MAXLN];
91
int pos_in_chain[MAXN];
92
int st[1 << (MAXLN + 1) + 5];
93
94
void construct(int i, int st_s, int st_e) {
95
    if (st_s == st_e) {
96
        st[i] = baseArray[st_s];
97
        return;
98
    }
99
    int mid = (st_s+st_e)/2;
100
    construct(2*i+1, st_s, mid);
101
    construct(2*i+2, mid+1, st_e);
102
    st[i] = max(st[2*i+1],st[2*i+2]);
103
}
104
105
void update(int i, int st_s, int st_e, int s, int val) {
106
    if (st_s > s || st_e < s) return;
107
    if (st_s == st_e && st_s == s) {
108
        st[i] = val;
109
        return;
110
    }
111
    int mid = (st_s+st_e)/2;
112
    update(2*i+1, st_s, mid,s,val);
113
    update(2*i+2, mid+1, st_e,s,val);
114
    st[i] = max(st[2*i+1],st[2*i+2]);
115
}
116
117
int query(int i, int st_s, int st_e, int s, int e) {
118
    if (st_s > e || st_e < s) return 0;
119
    if (s <= st_s && st_e <= e)  {
120
        return st[i];
121
    }
122
    int mid = (st_s+st_e)/2;
123
    return max(query(2*i+1, st_s, mid,s, e),query(2*i+2, mid+1, st_e,s,e));
124
}
125
126
void HLD(int curr, int prev, int cost) {
127
    if (head_of_chain[chainNo] == -1) {
128
        head_of_chain[chainNo] = curr;
129
    }
130
131
    chain[curr] = chainNo;
132
    posInBase[curr] = ptr;
133
    baseArray[ptr++] = cost;
134
135
    int sc = -1;
136
    int mss = 0;
137
    int nc = 0;
138
    REP(i,0,adj_list[curr].size()) {
139
        if (adj_list[curr][i] != prev && subsize[adj_list[curr][i]] > mss) {
140
            sc = adj_list[curr][i];
141
            nc = costs[curr][i];
142
            mss = subsize[adj_list[curr][i]];
143
        }
144
    }
145
146
    if (sc != -1) {
147
        HLD(sc,curr,nc);
148
    }
149
150
    REP(i,0,adj_list[curr].size()) {
151
        if (adj_list[curr][i] != prev && adj_list[curr][i] != sc) {
152
            chainNo++;
153
            HLD(adj_list[curr][i], curr, costs[curr][i]);
154
        }
155
    }
156
}
157
158
void dfs(int r, int p, int d = 0) {
159-
    par[r][0] = p;
159+
    par[r] = p;
160
    subsize[r] = 1;
161
    L[r] = d;
162
    REP(i,0,adj_list[r].size()) {
163
        if (adj_list[r][i] != p) {
164
            other_end[indexx[r][i]] = adj_list[r][i];
165
            dfs(adj_list[r][i],r,d+1);
166
            subsize[r] += subsize[adj_list[r][i]];
167
        }
168
    }
169
}
170
171
void change(int a, int b) {
172
    int u = other_end[a];
173
    update(0,0,ptr,posInBase[u],b);
174
}
175
176-
int LCS(int u, int v) {
176+
int LCA(int u, int v) {
177
    while (chain[u] != chain[v]) {
178-
        if (L[u] > L[v]) {
178+
        if (L[head_of_chain[chain[u]]] > L[head_of_chain[chain[v]]]) {
179
            u = head_of_chain[chain[u]];
180-
            u = par[u][0];
180+
            assert(u==1 || par[u] != -1);
181
            u = par[u];
182
        }
183
        else {
184-
            v = par[v][0];
184+
185
            assert(par[v] != -1);
186
            v = par[v];
187
        }
188
    }
189
    if (L[u] < L[v]) return u;
190
    return v;
191
}
192
193
int q(int a, int b) {
194
    if (a == b) return 0;
195
    int achain, bchain = chain[b], ans = -1;
196
    while(1) {
197
        achain = chain[a];
198-
            ans = max(ans,query(0,0,ptr,posInBase[a],posInBase[b]));
198+
199
            if (a == b) break;
200
            ans = max(ans,query(0,0,ptr,posInBase[b],posInBase[a]));
201
            break;
202
        }
203-
        a = par[a][0];
203+
204
        a = head_of_chain[achain];
205
        a = par[a];
206
    }
207
    return ans;
208-
int query(int a, int b) {
208+
209-
    int lcs = LCS(a, b);
209+
210-
    return max(q(lcs,a), q(lcs,b));
210+
int mquery(int a, int b) {
211
    int lca = LCA(a, b);
212
    return max(q(a,lca), q(b,lca));
213
}
214
215
int main(void) {
216
    ios_base::sync_with_stdio(0);
217
#ifndef ONLINE_JUDGE
218
    freopen("i.txt","r",stdin);
219
//    freopen("o.txt","w",stdout);
220
#endif
221
    int T;
222
    cin >> T;
223
    REP(i,0,T) {
224
        ptr = chainNo = 0;
225
        memset(head_of_chain, -1, sizeof head_of_chain);
226
        int N; cin >> N;
227
        REP(j,0,N+1) {
228
            adj_list[j].clear();
229-
            REP(k,0,MAXLN) par[j][k] = -1;
229+
230
            indexx[j].clear();
231
            par[j] = -1;
232
        }
233
        REP(j,1,N) {
234
            int a, b, c;
235
            cin >> a >> b >> c;
236
            adj_list[a].PB(b);
237
            adj_list[b].PB(a);
238
            costs[a].PB(c);
239
            costs[b].PB(c);
240
            indexx[a].PB(j);
241
            indexx[b].PB(j);
242
        }
243
        dfs(root,-1);
244
        HLD(root, -1, 0);
245
        construct(0,0,ptr);
246
        string s; int p1,p2;
247
        cin >> s;
248
        while(s[0] != 'D') {
249
            cin >> p1 >> p2;
250
            if (s[0] == 'C') {
251
                change(p1,p2);
252-
                cout << query(p1,p2) << endl;
252+
253
            else {
254
                cout << mquery(p1,p2) << endl;
255
            }
256
            cin >> s;
257
        }
258
        /*
259
        REP(l,0,2*N) {
260
            cout << st[l] << " ";
261
        }
262
        cout << "L " << LCA(4,5);
263
        cout << endl;
264
        */
265
    }
266
    return 0;
267
}