Pagini recente » Cod sursa (job #2574525) | Cod sursa (job #1532872) | Cod sursa (job #3151246) | Cod sursa (job #3170438) | Cod sursa (job #751649)
Cod sursa(job #751649)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const char InFile[]="heavypath.in";
const char OutFile[]="heavypath.out";
const int MaxN=100111;
const int AINTSIZE=4*MaxN;
ifstream fin(InFile);
ofstream fout(OutFile);
int N,M,V[MaxN],x,y,lant[MaxN],tata_lant[MaxN],g[MaxN],niv[MaxN],aint[AINTSIZE],lant_offset[MaxN],lant_dim[MaxN];
vector<int> G[MaxN],L[MaxN];
void DFS(int nod)
{
g[nod]=1;
int gmax=0;
for(vector<int>::iterator it=G[nod].begin();it!=G[nod].end();++it)
{
int &vcn=*it;
if(!niv[vcn])
{
niv[vcn]=niv[nod]+1;
DFS(vcn);
g[nod]+=g[vcn];
tata_lant[lant[vcn]]=nod;
if(g[gmax]<g[vcn])
{
gmax=vcn;
}
}
}
if(!gmax)
{
lant[nod]=++lant[0];
}
else
{
lant[nod]=lant[gmax];
}
L[lant[nod]].push_back(nod);
}
int AINT_lant=0,update_pos,update_val,AINT_offset,query_st,query_dr,query_sol;
void BuildAINT(int nod, int st, int dr)
{
if(st==dr)
{
aint[nod+AINT_offset]=V[L[AINT_lant][st-1]];
return;
}
int mid=st+((dr-st)>>1);
int l=nod<<1;
int r=l+1;
BuildAINT(l,st,mid);
BuildAINT(r,mid+1,dr);
if(aint[l+AINT_offset]>aint[r+AINT_offset])
{
aint[nod+AINT_offset]=aint[l+AINT_offset];
}
else
{
aint[nod+AINT_offset]=aint[r+AINT_offset];
}
}
void UpdateAINT(int nod, int st, int dr)
{
if(st==dr)
{
aint[nod+AINT_offset]=update_val;
return;
}
int mid=st+((dr-st)>>1);
int l=nod<<1;
int r=l+1;
if(update_pos<=mid)
{
UpdateAINT(l,st,mid);
}
else
{
UpdateAINT(r,mid+1,dr);
}
if(aint[l+AINT_offset]>aint[r+AINT_offset])
{
aint[nod+AINT_offset]=aint[l+AINT_offset];
}
else
{
aint[nod+AINT_offset]=aint[r+AINT_offset];
}
}
void QueryAINT(int nod, int st, int dr)
{
if(query_st<=st && dr<=query_dr)
{
if(query_sol<aint[nod+AINT_offset])
{
query_sol=aint[nod+AINT_offset];
}
return;
}
int mid=st+((dr-st)>>1);
int l=nod<<1;
int r=l+1;
if(query_st<=mid)
{
QueryAINT(l,st,mid);
}
if(query_dr>mid)
{
QueryAINT(r,mid+1,dr);
}
}
int main()
{
fin>>N>>M;
for(register int i=1;i<=N;++i)
{
fin>>V[i];
}
for(register int i=1;i<N;++i)
{
fin>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
niv[1]=1;
DFS(1);
tata_lant[lant[1]]=0;
for(register int i=1;i<=lant[0];++i)
{
reverse(L[i].begin(),L[i].end());
lant_dim[i]=L[i].size();
lant_offset[i]=lant_offset[i-1]+lant_dim[i-1]*4;
AINT_lant=i;
AINT_offset=lant_offset[i];
BuildAINT(1,1,lant_dim[i]);
}
for(register int i=1;i<=M;++i)
{
int op;
fin>>op>>x>>y;
if(op==0)
{
AINT_offset=lant_offset[lant[x]];
update_pos=niv[x]-niv[tata_lant[lant[x]]];
update_val=y;
UpdateAINT(1,1,lant_dim[lant[x]]);
}
else
{
int sol=0;
while(1)
{
query_sol=0;
if(lant[x]==lant[y])
{
AINT_offset=lant_offset[lant[x]];
query_st=niv[x]-niv[tata_lant[lant[x]]];
query_dr=niv[y]-niv[tata_lant[lant[y]]];
if(query_st>query_dr)
{
int aux=query_st;
query_st=query_dr;
query_dr=aux;
}
QueryAINT(1,1,lant_dim[lant[x]]);
if(sol<query_sol)
{
sol=query_sol;
}
break;
}
if(niv[tata_lant[lant[x]]]<niv[tata_lant[lant[y]]])
{
int aux=x;
x=y;
y=aux;
}
query_st=1;
query_dr=niv[x]-niv[tata_lant[lant[x]]];
AINT_offset=lant_offset[lant[x]];
QueryAINT(1,1,lant_dim[lant[x]]);
if(sol<query_sol)
{
sol=query_sol;
}
x=tata_lant[lant[x]];
}
fout<<sol<<"\n";
}
}
fin.close();
fout.close();
return 0;
}