Pagini recente » Cod sursa (job #1861106) | Cod sursa (job #1128050) | Cod sursa (job #2108887) | Cod sursa (job #819338) | Cod sursa (job #2092486)
#include <fstream>
#include <vector>
using namespace std;
//ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
int val [100100];
vector < vector < int > > gr (100100);
vector < bool > used (100100);
vector < vector < int > > arb (100100);
vector < vector < int > > Arb (100100);
vector < int > tata_lant (100100);
vector < int > lant (100100);
vector < int > lv (100100);
vector < int > pos (100100);
int cont = 0;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
int dfs(int root){
used[root] = true;
int MAX = 0;
int go = 0;
int last = 0;
for (auto &x : gr[root]){
if (used[x]){
last = x;
continue;
}
lv[x] = lv[root] + 1;
int val = dfs(x);
if (MAX < val){
MAX = val;
go = x;
}
}
if (go == 0){
cont++;
arb[cont].push_back(root);
lant[root] = cont;
pos[root] = 1;
}
else{
arb[lant[go]].push_back(root);
lant[root] = lant[go];
pos[root] = arb[lant[root]].size();
for (auto &x : gr[root]){
if (x == last || x == go){
continue;
}
tata_lant [lant[x]] = root;
}
}
return MAX + 1;
}
void Resize(){
for (int i=1; i<=cont; i++){
Arb[i].resize(arb[i].size() * 4);
}
}
int st , dr , poz , value , ARB;
void Update (int nod){
if (st == dr){
Arb[ARB][nod] = value;
return;
}
int mij = st + dr;
mij /= 2;
if (mij >= poz){
dr = mij;
Update(nod * 2);
}
else{
st = mij + 1;
Update(nod * 2 + 1);
}
Arb[ARB][nod] = max ( Arb[ARB][nod * 2] , Arb[ARB][nod * 2 + 1] );
}
int MIN , MAX;
void Querry (int NOD , int ST , int DR , int &maxx){
if (MIN <= ST && MAX >= DR){
maxx = max ( maxx , Arb[ARB][NOD] );
return;
}
int mij = ST + DR;
mij /= 2;
if (mij >= MIN){
Querry (NOD * 2 , ST , mij , maxx);
}
if (mij < MAX){
Querry (NOD * 2 + 1, mij + 1 , DR , maxx);
}
}
int main() {
InParser fin("heavypath.in");
ios::sync_with_stdio(false);
cout.tie(NULL);
int n , m;
fin>>n>>m;
for (int i=1; i<=n; i++){
fin>>val[i];
}
for (int i=1; i<n; i++){
int a , b;
fin>>a>>b;
gr[a].push_back(b);
gr[b].push_back(a);
}
dfs(1);
Resize();
for (int i=1; i<=n; i++){
st = 1;
dr = arb[lant[i]].size();
poz = pos[i];
value = val[i];
ARB = lant[i];
Update (1);
}
for (int i=1; i<=m; i++){
int test , x , y;
fin>>test>>x>>y;
if (test == 0){
val[x] = y;
st = 1;
dr = arb[lant[x]].size();
poz = pos[x];
value = val[x];
ARB = lant[x];
Update (1);
}
else{
int maxx = 0;
while ( lant[x] != lant[y] ){
int lv_x = lv [ arb [lant[x]] [arb [ lant[x] ].size() - 1 ]];
int lv_y = lv [ arb [lant[y]] [arb [ lant[y] ].size() - 1 ]];
if (lv_x > lv_y){
MIN = pos[x];
MAX = arb[lant[x]].size();
ARB = lant[x];
Querry(1, 1 , arb[lant[x]].size() , maxx);
x = tata_lant[lant[x]];
}
else{
MIN = pos[y];
MAX = arb[lant[y]].size();
ARB = lant[y];
Querry(1, 1 , arb[lant[y]].size() , maxx);
y = tata_lant[lant[y]];
}
}
MIN = min(pos[x] , pos[y]);
MAX = max(pos[x] , pos[y]);
ARB = lant[x];
Querry(1, 1 , arb[lant[x]].size() , maxx);
cout<<maxx<<'\n';
}
}
return 0;
}