Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <vector>
- #include <algorithm>
- using namespace std;
- ifstream cin("heavypath.in");
- ofstream cout("heavypath.out");
- #define maxn 100050
- #define pb push_back
- int maxim(int a,int b){if(a>b)return a;return b;}
- void swap(int&a,int&b){int aux=a;a=b,b=aux;}
- vector <int> g[maxn];
- int v[maxn], n, T;
- int viz[maxn],w[maxn],niv[maxn];
- int nL;
- int l[maxn],lDim[maxn],lNiv[maxn],lTata[maxn],lDif[maxn];
- vector <int>Chains[maxn];
- int arb[4*maxn];
- void df(int);
- void make_paths();
- void build(int,int,int,int,int);
- int querry(int,int,int,int,int,int);
- void update(int,int,int,int,int,int);
- int main()
- {
- int x,y,t;
- cin>>n>>T;
- for(int i=1;i<=n;++i)
- cin>>v[i];
- for(int i=1;i<n;++i){
- cin>>x>>y;
- g[x].pb(y);
- g[y].pb(x);
- }
- make_paths();
- int sol;
- for(;T--;){
- cin>>t>>x>>y;
- if(t==0)
- update(1,1,lDim[l[x]],lDif[l[x]],niv[x]-lNiv[l[x]],y);
- else{
- sol=-1;
- while(1){
- if(l[x]==l[y]){
- if(niv[x]>niv[y])
- swap(x,y);
- sol=maxim(sol,querry(1,1,lDim[l[x]],niv[x]-lNiv[l[x]],niv[y]-lNiv[l[x]],lDif[l[x]]));
- break;
- }
- if(lNiv[l[x]]<lNiv[l[y]])
- swap(x,y);
- sol=maxim(sol,querry(1,1,lDim[l[x]],1,niv[x]-lNiv[l[x]],lDif[l[x]]));
- x=lTata[l[x]];
- }
- cout<<sol<<'\n';
- }
- }
- }
- void df(int nod)
- {
- int mNods=-1,frunza=1;
- viz[nod]=1;
- w[nod]=1;
- for(auto it:g[nod])
- if(!viz[it]){
- frunza=0;
- niv[it]=niv[nod]+1;
- df(it);
- w[nod]+=w[it];
- if(mNods==-1)
- mNods=it;
- else
- if(w[mNods]<w[it])
- mNods=it;
- }
- if(frunza){
- l[nod]=++nL;
- lDim[l[nod]]=1;
- Chains[l[nod]].pb(nod);
- return;
- }
- l[nod]=l[mNods];
- ++lDim[l[nod]];
- Chains[l[nod]].pb(nod);
- for(auto it:g[nod]){
- if(mNods==it||niv[nod]>niv[it])
- continue;
- lNiv[l[it]]=niv[nod];
- lTata[l[it]]=nod;
- }
- }
- void build(int nod,int start,int end, int decalaj,int lant)
- {
- if(start==end){
- arb[nod+decalaj]=v[Chains[lant][start-1]];
- return;
- }
- int mid=(start+end)/2;
- build(nod*2,start, mid, decalaj, lant);
- build(nod*2+1,mid+1,end,decalaj, lant);
- arb[nod+decalaj]=maxim(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
- }
- void make_paths()
- {
- niv[1]=1;
- df(1);
- for(int i=1;i<=nL;++i){
- if(i>1)
- lDif[i]=lDif[i-1] + lDim[i-1]*4;
- reverse(Chains[i].begin(),Chains[i].end());
- build(1,1,lDim[i],lDif[i],i);
- }
- }
- void update(int nod, int start, int end,int decalaj, int poz, int val)
- {
- if(start==end){
- arb[nod+decalaj]=val;
- return;
- }
- int mid=(start+end)/2;
- if(poz<=mid)
- update(nod*2,start, mid, decalaj, poz, val);
- else
- update(nod*2+1,mid+1,end,decalaj,poz,val);
- arb[nod+decalaj]=maxim(arb[nod*2+decalaj],arb[nod*2+1+decalaj]);
- }
- int querry(int nod, int start, int end, int qstart,int qend,int decalaj)
- {
- if(qstart<=start&&end<=qend)
- return arb[nod+decalaj];
- int mid=(start+end)/2, rez=-1;
- if(qstart<=mid)
- rez=maxim(rez,querry(nod*2,start, mid, qstart, qend, decalaj));
- if(qend>mid)
- rez=maxim(rez,querry(nod*2+1,mid+1,end, qstart,qend, decalaj));
- return rez;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement