Mai intai trebuie sa te autentifici.
Cod sursa(job #3216615)
Utilizator | Data | 18 martie 2024 18:05:31 | |
---|---|---|---|
Problema | Heavy Path Decomposition | Scor | 100 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva educationala | Marime | 2.59 kb |
#include <bits/stdc++.h>
#define NMAX 100010
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int heavy[NMAX],lv[NMAX],poz[NMAX],head[NMAX],tree[4*NMAX],tata[NMAX],euler[NMAX],val[NMAX];
vector<int>v[NMAX];
int n,q,lg;
void build(int node,int left,int right)
{
if(left==right)
{
tree[node]=val[euler[left]];
return;
}
int mij=(left+right)/2;
build(2*node,left,mij);
build(2*node+1,mij+1,right);
tree[node]=max(tree[2*node],tree[2*node+1]);
}
void update(int node,int left,int right,int pos,int val)
{
if(left==right)
{
tree[node]=val;
return;
}
int mij=(left+right)/2;
if(pos<=mij)
update(2*node,left,mij,pos,val);
else
update(2*node+1,mij+1,right,pos,val);
tree[node]=max(tree[2*node],tree[2*node+1]);
}
int query(int node,int left,int right,int st,int dr)
{
if(st<=left && right<=dr)
return tree[node];
int mij=(left+right)/2,a=0,b=0;
if(st<=mij)
a=query(2*node,left,mij,st,dr);
if(mij<dr)
b=query(2*node+1,mij+1,right,st,dr);
return max(a,b);
}
int dfs(int node,int parent)
{
lv[node]=lv[parent]+1;
tata[node]=parent;
int total=1,maxi=0;
for(auto it:v[node])
if(it!=parent)
{
int cnt=dfs(it,node);
total+=cnt;
if(cnt>maxi)
maxi=cnt,heavy[node]=it;
}
return total;
}
void create_path(int node,int cap,int parent)
{
head[node]=cap;
euler[++lg]=node;
poz[node]=lg;
if(heavy[node]!=0)
create_path(heavy[node],cap,node);
for(auto it:v[node])
if(it!=parent && it!=heavy[node])
create_path(it,it,node);
}
int query_hld(int a,int b)
{
int maxi=0;
while(head[a]!=head[b])
{
if(lv[head[a]]>lv[head[b]])
swap(a,b);
maxi=max(maxi,query(1,1,n,poz[head[b]],poz[b]));
b=tata[head[b]];
}
if(lv[a]>lv[b])
swap(a,b);
maxi=max(maxi,query(1,1,n,poz[a],poz[b]));
return maxi;
}
int main()
{
fin>>n>>q;
for(int i=1;i<=n;i++)
fin>>val[i];
for(int i=1;i<n;i++)
{
int x,y;
fin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1,0);
create_path(1,1,0);
build(1,1,n);
while(q--)
{
int t,x,y;
fin>>t>>x>>y;
///cout<<x<<" "<<y<<'\n';
if(t==0)
update(1,1,n,poz[x],y);
else
fout<<query_hld(x,y)<<'\n';
}
return 0;
}