Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- ofstream fout("heavypath.out");
- ifstream fin("heavypath.in");
- const int NMax = 100010;
- int niv[NMax];
- int sub[NMax];
- int path[NMax];
- vector<int> P[NMax];
- vector<int> G[NMax];
- int parent[NMax];
- int val[NMax];
- int k, n, m, x, y;
- int T[NMax][NMax];
- void makePaths(int node, int prev, int level){
- int maxi = 0;
- int connect = 0;
- niv[node] = level;
- for(int i = 0; i < G[node].size(); i++){
- int next = G[node][i];
- if(next == prev) continue;
- makePaths(next, node, level + 1);
- if(sub[next] > maxi){
- maxi = sub[next];
- connect = next;
- }
- }
- if(!maxi){
- P[++k].push_back(node);
- path[node] = k;
- sub[node] = 1;
- return;
- }
- P[path[connect]].push_back(node);
- path[node] = path[connect];
- sub[node] = sub[connect];
- for(int i = 0; i < G[node].size(); i++){
- int next = G[node][i];
- if(next == prev) continue;
- if(next != connect){
- parent[path[next]] = node;
- }
- }
- }
- void reversePaths()
- {
- for(int i = 1; i <= k; i++){
- reverse(P[i].begin(), P[i].end());
- }
- }
- void update(int t[], int pos, int st, int dr, int val){
- if(st == dr){
- t[pos] = val;
- return;
- }
- int mid = (st + dr) / 2;
- if(pos <= mid) update(t, pos * 2, st, mid, val);
- else update(t, pos * 2 + 1, mid + 1, dr, val);
- t[pos] = max(t[pos * 2], t[pos * 2 + 1]);
- }
- int maxim(int t[], int st, int dr, int l, int r, int pos){
- if(st==l && dr==r)
- {
- return t[pos];
- }
- int mij = (l+r)/2, nr1 = 0, nr2 = 0;
- if(st <= mij) nr1 = maxim(t, st, min(dr, mij), l, mij, pos * 2);
- if(dr > mij) nr2 = maxim(t, max(mij+1, st), dr, mij + 1, r, pos * 2 + 1);
- return max(nr1,nr2);
- }
- void makeTrees(){
- for(int i = 1; i <= k; i++){
- for(int j = 0; j < P[i].size(); j++){
- update(T[i], 1, 1, P[i].size(), val[P[i][j]]);
- pos[P[i][j]] = j;
- }
- }
- }
- int solve2(int x, int y){
- int rez = val[x];
- while(x != y){
- if(niv[parent[path[x]]] < niv[parent[path[y]]]) swap(x, y);
- if(path[x] == path[y]){
- rez = max(rez, maxim(T[path[x]], min(pos[x], pos[y]), max(pos[x],pos[y]), 1, P[path[x]].size()), 1);
- y = x;
- }
- else{
- rez = max(rez, maxim(T[path[x]], 1, pos[x], 1, P[path[x]].size()), 1);
- x = parent[path[x]];
- }
- }
- return rez;
- }
- void query(){
- for(int i = 1; i <= m; i++){
- fin >> o >> x >> y;
- if(o == 1){
- val[x] = y;
- update(path[x], 1, 1, P[path[x]].size(), y);
- }
- else{
- fout << solve2(x, y) << '\n';
- }
- }
- }
- int main()
- {
- fin >> n >> m;
- for(int i = 1; i <= n; i++) fin >> val[i];
- for(int i = 1; i < n; i++){
- fin >> x >> y;
- G[x].push_back(y);
- G[y].push_back(x);
- }
- makePaths(1, 0, 0);
- reversePaths();
- makeTrees();
- query();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement