Submission #1268041

#TimeUsernameProblemLanguageResultExecution timeMemory
1268041uzukishinobuGrapevine (NOI22_grapevine)C++20
100 / 100
909 ms536324 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a,b;
vector<pair<int,int>> z[1000005];
int high[1000005];
int child[100005];
int sz;
int par[1000005];
int del[1000005];
int sz1[1000005];
int inf= (int)1e15;

void predfs(int i,int parent){
     child[i]=1;
     for (auto [p,w]:z[i]){
          if (p==parent || del[p]){
              continue;
          }
          predfs(p,i);
          child[i]+=child[p];
     }
}

int centroid(int i,int parent){
   for (auto [p,w]:z[i]){
        if (p==parent || del[p]){
            continue;
        }
        if (child[p]>sz/2){
            return centroid(p,i);
        }
   }
   return i;
}
struct node{
      int cur;
      int min1;
      int val;
      int lazy;
};
int cur;
vector <node> f[100005];
void push(int id,int cen){
    if (f[cen][id].lazy!=0){
        f[cen][id*2].lazy+=f[cen][id].lazy;
        f[cen][id*2+1].lazy+=f[cen][id].lazy;

        f[cen][id*2].val+=f[cen][id].lazy;
        f[cen][id*2+1].val+=f[cen][id].lazy;

        if (f[cen][id*2].min1 < inf) f[cen][id*2].min1 += f[cen][id].lazy;
        if (f[cen][id*2+1].min1 < inf) f[cen][id*2+1].min1 += f[cen][id].lazy;

        f[cen][id].lazy=0;
    }
}
void update(int cen,int id,int l,int r,int x,int y,int val){
    if (x>r || y<l){
        return;
    }
    if (l>=x && y>=r){
        f[cen][id].val+=val;
        if (f[cen][id].min1 < inf) f[cen][id].min1+=val;
        f[cen][id].lazy+=val;
        return;
    }
    int mid=(l+r)/2;
    push(id,cen);
    update(cen,id*2,l,mid,x,y,val);
    update(cen,id*2+1,mid+1,r,x,y,val);
    f[cen][id].min1=min(f[cen][id*2].min1,f[cen][id*2+1].min1);
}

void update1(int cen,int id,int l,int r,int pos){
     if (l==r){
         f[cen][id].cur^=1;
         if (f[cen][id].cur){
             f[cen][id].min1=f[cen][id].val;
         }else{
             f[cen][id].min1=inf;
         }
         return;
     }
     int mid=(l+r)/2;
     push(id,cen);
     if (pos<=mid){
         update1(cen,id*2,l,mid,pos);
     }else{
         update1(cen,id*2+1,mid+1,r,pos);
     }
     f[cen][id].min1=min(f[cen][id*2].min1,f[cen][id*2+1].min1);
}

int get(int cen,int id,int l,int r,int pos){
    if (l==r){
        return f[cen][id].val;
    }
    int mid=(l+r)/2;
    push(id,cen);
    if (pos<=mid){
        return get(cen,id*2,l,mid,pos);
    }else{
        return get(cen,id*2+1,mid+1,r,pos);
    }
}

int sta[100005][55];
int fin[100005][55];
int tour;
unordered_map<int,int> m[1000005];

void dfs(int i,int parent,int val,int cen){
     tour++;
     sta[i][high[cen]]=tour;
     update(cen,1,1,sz1[cen],sta[i][high[cen]],sta[i][high[cen]],val);
     for (auto [p,w]:z[i]){
          if (p==parent || del[p]){
              continue;
          }
          dfs(p,i,val+w,cen);
     }
     fin[i][high[cen]]=tour;
}

void decompose(int i,int parent){

    predfs(i,0);
    sz=child[i];
    int cen=centroid(i,0);
//    cerr << cen << "\n";
    sz1[cen]=sz;
    high[cen]=high[parent]+1;
    par[cen]=parent;
    int SZ = 4*sz + 50;
    f[cen].assign(SZ+5, {0, (int)inf, 0, 0});
    for (int j=1;j<=4*sz+2;j++){
         f[cen][j].min1=inf;
         f[cen][j].val=0;
         f[cen][j].lazy=0;
         f[cen][j].cur=0;
    }
//    cerr << cen << "\n";
    cur++;
    del[cen]=cur;
    tour=0;
    dfs(cen,cen,0,cen);
    for (auto [p,w]:z[cen]){
         if (p==parent || del[p]){
             continue;
         }
//         cerr << p << " ";
         decompose(p,cen);
    }
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> a >> b;
    for (int i=1;i<a;i++){
         int x,y,t;
         cin >> x >> y >> t;
         z[x].push_back({y,t});
         z[y].push_back({x,t});
         m[x][y]=t;
         m[y][x]=t;
    }
    decompose(1,0);

//    for (int i=1;i<=a;i++){
//         cerr << par[i] << " ";
//    }
//    cerr << "\n";
    while (b--){
         int c;
         cin >> c;
         if (c==1){
             int x;
             cin >> x;
             int p=x;
             int res=inf;
             while (p!=0){
                  int pos = sta[x][high[p]];
                  if (pos==0){ p=par[p]; continue; }
                  int val=f[p][1].min1 + get(p,1,1,sz1[p], pos);
                  res=min(res,val);
                  p=par[p];
             }
             if (res==inf){
                 cout << -1 << "\n";
             }else{
                 cout << res << "\n";
             }
         }else if (c==2){
             int x;
             cin >> x;
             int p=x;
             while (p!=0){
 //                 cerr << p << " ";
                  int pos = sta[x][high[p]];
                  if (pos!=0) update1(p,1,1,sz1[p],pos);
                  p=par[p];
             }
//             cerr << "\n";
         }else{
             int x,y,t;
             cin >> x >> y >> t;
             int ox = x, oy = y;
             int u0 = ox, v0 = oy;
             if (del[u0] > del[v0]) swap(u0, v0);
             int oldw = 0;
             if (m[u0].find(v0) != m[u0].end()) oldw = m[u0][v0];
             int delta = t - oldw;
             int p = u0;
             while (p!=0){
                  int u = u0, v = v0;
                  int pos_u = sta[u][high[p]];
                  int pos_v = sta[v][high[p]];
                  if (pos_u==0 || pos_v==0){
                      p = par[p];
                      continue;
                  }
                  if (pos_u < pos_v) swap(u,v), swap(pos_u,pos_v);
                  update(p,1,1,sz1[p], pos_u, fin[u][high[p]], delta);
                  p=par[p];
             }
             m[ox][oy]=m[oy][ox]=t;
         }
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...