Cod sursa(job #974543)

Utilizator mitrutstrutMitrea Andrei Ionut mitrutstrut Data 17 iulie 2013 14:41:57
Problema Heavy Path Decomposition Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.35 kb
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <bitset>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <ctime>
#include <string>
#include <cstring>
#include <iomanip>
#include <algorithm>
using namespace std;
ifstream ff("heavypath.in");
ofstream gg("heavypath.out");
#define nmax 100001
#define inf 0x3f3f3f3f
vector<int> vv[nmax], oo[nmax], bb[nmax];
int s, a, b, n, m, aa[nmax], ll[nmax], pp[nmax], rr[nmax], tt[nmax], kk[nmax];
bool ww[nmax];
 
// void clc(int x){
    // int y, l=vv[x].size();
    // ww[x]=1;
    // for(int i=0;i<l;i++){
        // y=vv[x][i];
        // if(!ww[y])dfs(y);
        // rr[x] += rr[y];
    // }
    // rr[x]++;
// }
 
void dfs(int x,int r){
    int y, k=-1, l=vv[x].size();
    ww[x]=1;
    kk[x]=r;
    for(int i=0;i<l;i++){
        y=vv[x][i];
        if(!ww[y]){
            dfs(y,r+1);
            tt[y]=x;
            rr[x]+=rr[y];
        }
        if(kk[y]>=kk[x] && (k==-1 || rr[y]>rr[k]))k=y;
    }
    rr[x]++;
    if(k==-1){
        ll[0]++;
        ll[x]=ll[0];
        oo[ll[x]].push_back(x);
        rr[x]=1;
    } else {
        ll[x]=ll[k];
        oo[ll[x]].push_back(x);
    }
}
 
void upd(vector<int> &oo, int n, int l, int r){
    if(l==r){ oo[n]=b; } else {
        int m=(l+r)/2;
        if(a<=m)upd(oo, 2*n, l, m); else
            upd(oo, 2*n+1, m+1, r);
        oo[n]=max(oo[2*n], oo[2*n+1]); }
}
  
void qry(vector<int> &oo, int n,int l,int r){
    if(a<=l&&r<=b){ s=max(s,oo[n]); } else {
        int m=(l+r)/2;
        if(a<=m)qry(oo, 2*n, l, m);
        if(b>m)qry(oo, 2*n+1, m+1, r); }
}
  
int main(){
    int o;
    ff >> n >> m;
    for(int i=1;i<=n;i++) ff >> aa[i];
    for(int i=1;i<n;i++){
        ff >> a >> b;
        vv[a].push_back(b);
        vv[b].push_back(a);
    }
    //clc(1);
    //memset(ww, 0, sizeof(ww));
    dfs(1,1);
    //for(int i=1;i<=n;i++) gg << rr[i] << " "; gg << "\n";
    int deb=0;
    for(int i=1;i<=n;i++){
        reverse(oo[i].begin(), oo[i].end());
        int e=log(oo[i].size())/log(2);
        bb[i].resize(1<<(e+2));
    }
    for(int i=1;i<=n;i++)
    for(int j=0;j<(int)oo[i].size();j++) pp[oo[i][j]]=j+1;
    //for(int i=1;i<=n;i++) gg << kk[i] << " "; gg << "\n";
     
    for(int i=1;i<=n;i++){
        for(int j=0;j<(int)oo[i].size();j++){
            a=j+1; b=aa[oo[i][j]];
            upd(bb[i], 1, 1, oo[i].size());
        }
    }
     
    // int l=ll[0];
    // for(int i=1;i<=l;i++){
        // for(int j=0;j<oo[i].size();j++) gg << oo[i][j] << " ";
        // gg << "\n";
    // }
    int x, y, q;
    for(int i=1;i<=m;i++){
        ff >> o >> a >> b;
        if(o==0) {
            x=a; a=pp[a];
            upd(bb[ll[x]], 1, 1, oo[ll[x]].size());
        //  for(int i=1;i<bb[2].size();i++) cout << bb[2][i] << " "; cout <<"\n";
            } else {
            x=a, y=b, q=0;
            //gg << "Q( "<< x << " , " << y << " )\n";
            do{
                if(ll[x]==ll[y]){
                    a=pp[x]; b=pp[y]; if(a>b) swap(a, b);
                    //gg << "e " << a << " " << b << "\n";
                    s=0;
                    qry(bb[ll[x]], 1, 1, oo[ll[x]].size());
                    q=max(q, s);
                    x=y;
                } else {
                    if(kk[ tt[oo[ll[x]][0]] ]>kk[ tt[oo[ll[y]][0]] ]){
                        a=1; b=pp[x];
                        //gg << "l " << a << " " << b << "\n";
                        s=0;
                        qry(bb[ll[x]], 1, 1, oo[ll[x]].size());
                        q=max(q, s);
                        x=tt[ oo[ll[x]][0] ];
                    } else {
                        a=1; b=pp[y];
                        //gg << "r " << a << " " << b << "\n";
                        s=0;
                        qry(bb[ll[y]], 1, 1, oo[ll[y]].size());
                        q=max(q, s);
                        y=tt[ oo[ll[y]][0] ];
                    }
                }
            }while(x!=y);
            s=0; a=pp[x]; b=pp[x];
            qry(bb[ll[x]], 1, 1, oo[ll[x]].size());
            q=max(q, s);
            gg << q << "\n";
        }
    }
    // int l=ll[0];
    // for(int i=1;i<=l;i++){
        // for(int j=0;j<bb[i].size();j++) gg << bb[i][j] << " ";
        // gg << "\n";
    // }
    return 0;
}