Pagini recente » oni_10_0 | Cod sursa (job #3364233) | Cod sursa (job #3364197) | Cod sursa (job #3364334) | Cod sursa (job #3364154)
#include <fstream>
#include <vector>
#include <climits>
using namespace std;
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
#define MAXN 100000
struct Node{
int val;
int tin,size,parent,depth;
int heavy,head;
vector<int> adj;
}nodes[MAXN+1];
int vals[MAXN+1];
struct SegmentTree{
int arr[4*MAXN+1];
int sz;
void init(int n,int v[]){
sz=1<<(32-__builtin_clz(n-1));
for(int i=0;i<2*sz;i++){
arr[i]=INT_MIN;
}
for(int i=1;i<=n;i++){
arr[i+sz]=v[i];
}
for(int i=sz-1;i>=1;i--){
arr[i]=max(arr[2*i],arr[2*i+1]);
}
}
int getMax(int l,int r){
int res=INT_MIN;
l+=sz;
r+=sz;
while(l<=r){
if(l&1){
res=max(res,arr[l++]);
}
l>>=1;
if(!(r&1)){
res=max(res,arr[r--]);
}
r>>=1;
}
return res;
}
void pointUpdate(int pos,int val){
pos+=sz;
arr[pos]=val;
pos>>=1;
while(pos){
arr[pos]=max(arr[2*pos],arr[2*pos+1]);
pos>>=1;
}
}
}segtree;
void computeHeavy(int u,int p){
nodes[u].size=1;
nodes[u].parent=p;
nodes[u].depth=nodes[p].depth+1;
for(int v:nodes[u].adj){
if(v!=p){
computeHeavy(v,u);
if(nodes[v].size>nodes[nodes[u].heavy].size){
nodes[u].heavy=v;
}
nodes[u].size+=nodes[v].size;
}
}
}
void dfsFlatten(int u,int head){
static int timer=0;
nodes[u].tin=++timer;
nodes[u].head=head;
vals[nodes[u].tin]=nodes[u].val;
if(nodes[u].heavy){
dfsFlatten(nodes[u].heavy,head);
}
for(int v:nodes[u].adj){
if(v!=nodes[u].parent&&v!=nodes[u].heavy){
dfsFlatten(v,v);
}
}
}
int query(int u,int v){
int ans=0;
while(nodes[u].head!=nodes[v].head){
if(nodes[nodes[v].head].depth>nodes[nodes[u].head].depth){
swap(v,u);
}
ans=max(ans,segtree.getMax(nodes[nodes[u].head].tin,nodes[u].tin));
u=nodes[nodes[u].head].parent;
}
if(nodes[u].depth>nodes[v].depth){
swap(u,v);
}
ans=max(ans,segtree.getMax(nodes[u].tin,nodes[v].tin));
return ans;
}
int main(){
int n,m,i,u,v,type;
cin>>n>>m;
for(i=1;i<=n;i++){
cin>>nodes[i].val;
}
for(i=0;i<n-1;i++){
cin>>u>>v;
nodes[u].adj.push_back(v);
nodes[v].adj.push_back(u);
}
computeHeavy(1,0);
dfsFlatten(1,1);
segtree.init(n,vals);
while(m--){
cin>>type>>u>>v;
if(type==0){
segtree.pointUpdate(nodes[u].tin,v);
}else{
cout<<query(u,v)<<"\n";
}
}
return 0;
}