Cod sursa(job #2986381)

Utilizator mmocanuMocanu Mihai-Adrian mmocanu Data 28 februarie 2023 14:54:00
Problema Heavy Path Decomposition Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.61 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define MAXN 100005
#define INFI 1000006
#define bol bool
using namespace std;

struct NOD{
  int cost;
  int last;
  int adan;
  int pozi;
  int loca;
  int fath;
  bol hevy;
  bol visi;
};

struct LFD{
  int left;
  int righ;
};


vector <int> graf[MAXN];
NOD poit[MAXN];
LFD stdr[MAXN];
int aint[MAXN*4];
int siru[MAXN];
int eule[MAXN*2];
int alca[MAXN*8];
int t;

int Min(int x,int y){
  return x<y?x:y;
}

int Max(int x,int y){
  return x>y?x:y;
}

int DFS(int node,int adan){
  int ma,x,s,aux;

  s=1;
  ma=-1;
  x=-1;

  poit[node].adan=adan;
  poit[node].visi=true;

  poit[node].last=t;
  eule[t++]=adan;

  for(int neigh : graf[node]){
    if(!poit[neigh].visi){

      aux=DFS(neigh,adan+1);

      poit[node].last=t;
      eule[t++]=adan;

      if(ma<aux){
        ma=aux;
        x=neigh;
      }
      s+=aux;
    }
  }

  if(x!=-1){
    poit[x].hevy=true;
  }

  return s;
}

void CreateLCA(int x,int y,int poz){
  int mij;
  if(x==y){
    alca[poz]=eule[x];
    return;
  }
  mij=(x+y)/2;
  CreateLCA(x    ,mij,poz*2  );
  CreateLCA(mij+1,y  ,poz*2+1);
  alca[poz]=Min(alca[poz*2],alca[poz*2+1]);
}

int LCA(int x,int y,int i,int j,int poz){
  int mij;
  if(i<=x && y<=j){
    return alca[poz];
  }
  if(y<i || j<x){
    return INFI;
  }
  mij=(x+y)/2;
  return Min(LCA(x    ,mij,i,j,poz*2  ),
             LCA(mij+1,y  ,i,j,poz*2+1));
}

void MakeHeavyDecomp(int n){
  int i,m,t,s,node;

  m=0;
  t=1;
  for(i=1;i<=n;i++){
    if(poit[i].hevy==0){
      stdr[m].left=t;
      s=1;
      node=i;
      while(s==1){
        poit[node].loca=t;
        siru[t++]=node;
        poit[node].pozi=m;
        s=0;
        for(int neigh : graf[node]){
          if(poit[neigh].hevy){
            node=neigh;
            s=1;
          }
        }
      }
      stdr[m].righ=t;
      m++;
    }
  }
}

void CreateAINT(int x,int y,int poz){
  int mij;
  if(x==y){
    aint[poz]=poit[siru[x]].cost;
    return;
  }
  mij=(x+y)/2;
  CreateAINT(x    ,mij,poz*2  );
  CreateAINT(mij+1,y  ,poz*2+1);
  aint[poz]=Max(aint[poz*2],aint[poz*2+1]);
}

int SearchAINT(int x,int y,int i,int j,int poz){
  int mij;
  if(i<=x && y<=j){
    return aint[poz];
  }
  if(j<x || y<i){
    return 0;
  }
  mij=(x+y)/2;
  return Max(SearchAINT(x    ,mij,i,j,poz*2  ),
             SearchAINT(mij+1,y  ,i,j,poz*2+1));
}

void UpdateAINT(int x,int y,int i,int val,int poz){
  int mij;
  if(x==i && i==y){
    aint[poz]=val;
    return;
  }
  if(i<x || y<i){
    return;
  }
  mij=(x+y)/2;
  UpdateAINT(x    ,mij,i,val,poz*2  );
  UpdateAINT(mij+1,y  ,i,val,poz*2+1);
  aint[poz]=Max(aint[poz*2],aint[poz*2+1]);
}

int main(){
  int n,m,i,x,y,inter,st,dr,r,j,aux,last;
  FILE *fin,*fout;
  fin=fopen("heavypath.in","r");
  fout=fopen("heavypath.out","w");
  fscanf(fin,"%d%d",&n,&m);

  for(i=1;i<=n;i++){
    fscanf(fin,"%d",&poit[i].cost);
    poit[i].fath=-1;
  }

  for(i=1;i<n;i++){
    fscanf(fin,"%d%d",&x,&y);
    poit[y].fath=x;
    graf[x].push_back(y);
  }

  DFS(1,1);
  CreateLCA(1,2*n-2,1);
  MakeHeavyDecomp(n);
  CreateAINT(1,n,1);

  printf("last adan pozi loca fath hevy siru\n");
  for(i=1;i<=n;i++){
    printf("%4d %4d %4d %4d %4d %4d %4d\n",   poit[i].last,
                                              poit[i].adan,
                                              poit[i].pozi,
                                              poit[i].loca,
                                              poit[i].fath,
                                              poit[i].hevy,
                                              siru[i]);
  }
  for(i=0;i<=2*n;i++){
    printf("%d ",eule[i]);
  }


  for(i=0;i<m;i++){
    fscanf(fin,"%d%d%d",&t,&x,&y);
    if(t==0){
      UpdateAINT(1,n,poit[x].loca,y,1);
    }else{
      st=poit[x].last;
      dr=poit[y].last;
      if(st>dr){
        aux=dr;
        dr=st;
        st=aux;
      }
      inter=LCA(1,2*n-2,st,dr,1);
      r=-1;
      for(j=0;j<2;j++){
        if(j==0){
          last=x;
        }else{
          last=y;
        }
        while(poit[siru[stdr[poit[last].pozi].left]].adan>inter){
          r=Max(r,SearchAINT(1,n,stdr[poit[last].pozi].left,poit[last].loca,1));
          last=poit[siru[stdr[poit[last].pozi].left]].fath;
        }
        r=Max(r,SearchAINT(1,n,stdr[poit[last].pozi].left+inter-poit[stdr[poit[last].pozi].left].adan,poit[last].loca,1));
      }
      fprintf(fout,"%d\n",r);
    }
  }

  fclose(fin);
  fclose(fout);
  return 0;
}