Submission #1126418

#TimeUsernameProblemLanguageResultExecution timeMemory
1126418_rain_Grapevine (NOI22_grapevine)C++20
0 / 100
1602 ms184976 KiB
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int>ii; #define fi first #define se second #define name "main" #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define FORD(i,a,b) for(int i=(b);i>=(a);--i) #define N 1'00'000 #define MAXL 16 const LL INF=(LL)1e18; vector<int>ke[N+2]; void add_canh(int u,int v){ ke[u].push_back(v),ke[v].push_back(u); return; } int n,q; int u[N+2],v[N+2],w[N+2]={}; class IT{ public: #define lef(id) id*2 #define rig(id) id*2+1 vector<LL>st,lz,mn; void init(int n){ st.assign(n*4+2,0),lz.assign(n*4+2,0),mn.assign(n*4+2,INF); return; } void pushdown(int id){ LL &t=lz[id]; st[lef(id)]+=t,lz[lef(id)]+=t; if (mn[lef(id)]!=INF) mn[lef(id)]+=t; st[rig(id)]+=t,lz[rig(id)]+=t; if (mn[rig(id)]!=INF) mn[rig(id)]+=t; t=0; return; } void modify(int id,int l,int r,int u,int v,int val){ if (l>v||r<u) return; if (u<=l&&r<=v){ st[id]+=val; lz[id]+=val; if (mn[id]!=INF) mn[id]+=val; return; } int m=l+r>>1; pushdown(id); modify(lef(id),l,m,u,v,val); modify(rig(id),m+1,r,u,v,val); st[id]=min(st[lef(id)],st[rig(id)]); mn[id]=min(mn[lef(id)],mn[rig(id)]); } void soak(int id,int l,int r,int p){ if (l>p||r<p) return; if (l==r) mn[id]=st[id]; else{ int m=(l+r)>>1; pushdown(id); soak(lef(id),l,m,p); soak(rig(id),m+1,r,p); st[id]=min(st[lef(id)],st[rig(id)]); mn[id]=min(mn[lef(id)],mn[rig(id)]); } } LL Get(int id,int l,int r,int u,int v){ if (l>v||r<u) return INF; if (u<=l&&r<=v) return st[id]; int m=l+r>>1; pushdown(id); return min(Get(lef(id),l,m,u,v),Get(rig(id),m+1,r,u,v)); } }; IT st[N+2]; map<pair<int,int>,int>mp; namespace Centroid{ int sub[N+2]={},up[N+2]={},dep[N+2]={},sta[MAXL+2][N+2]={},fin[MAXL+2][N+2]={},times[MAXL+2]; int sz=0; bool del[N+2]={}; multiset<LL>bag[N+2]; void dfs_size(int u,int p){ sub[u]=1; for(auto&v:ke[u]){ if (v==p||del[v]) continue; dfs_size(v,u); sub[u]+=sub[v]; } return; } int Find_centroid(int u,int p,int half){ for(auto&v:ke[u]) { if (v==p||del[v]) continue; if (sub[v]>half) return Find_centroid(v,u,half); } return u; } void dfs(int layer,int root,int u,int p){ sta[layer][u]=++times[root]; for(auto&v:ke[u]){ if (v==p||del[v]) continue; dfs(layer,root,v,u); } fin[layer][u]=times[root]; return; } void build_centroid(int u,int p){ dfs_size(u,u); u=Find_centroid(u,u,sub[u]/2); dep[u]=dep[p]+1; up[u]=p; dfs(dep[u],u,u,u); st[u].init(times[u]); del[u]=true; for(auto&v:ke[u]) { if (!del[v]) build_centroid(v,u); } return; } void anneal(int u,int v,int w){ if (u>v) swap(u,v); int change=w-mp[{u,v}]; mp[{u,v}]=w; if (dep[u]>dep[v]) swap(u,v); int node=u; while (u!=0){ st[u].modify(1,1,times[u],sta[dep[u]][v],fin[dep[u]][v],change); u=up[u]; } return; } void soaking(int u){ int node=u; while(node!=0){ st[node].soak(1,1,times[node],sta[dep[node]][u]); node=up[node]; } } LL Find(int u){ LL ans=INF; int node=u; while (node!=0){ int k=sta[dep[node]][u]; ans=min(ans,st[node].Get(1,1,times[node],k,k)+st[node].mn[1]); node=up[node]; } return ans; } } using namespace Centroid; int32_t main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n>>q; FOR(i,1,n-1){ cin>>u[i]>>v[i]>>w[i]; add_canh(u[i],v[i]); } build_centroid(1,0); FOR(i,1,n-1) anneal(u[i],v[i],w[i]); while(q--){ int t; cin>>t; if (t==1) { int x; cin>>x; cout<<Find(x)<<'\n'; } if (t==2){ int x; cin>>x; soaking(x); } if (t==3){ int a,b,w; cin>>a>>b>>w; anneal(a,b,w); } } exit(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...