Submission #1126475

#TimeUsernameProblemLanguageResultExecution timeMemory
1126475_rain_Grapevine (NOI22_grapevine)C++20
100 / 100
1413 ms189096 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]={}; bool ap[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,int t){ if (l>p||r<p) return; if (l==r) { mn[id]=(t?st[id]:INF); } else{ int m=(l+r)>>1; pushdown(id); soak(lef(id),l,m,p,t); soak(rig(id),m+1,r,p,t); 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[N+2]; int sz=0; bool del[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]; // if (root==1){ // cout<<"(DEBUG)\n"; // cout<<u<<' '<<p<<'\n'; // cout<<"(END - DEBUG)\n"; // } 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); // cout<<u<<' '<<p<<'\n'; 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; // cout<<change<<'\n'; if (dep[u]>dep[v]) swap(u,v); int node=u; while (node!=0){ if (sta[dep[node]][u]>sta[dep[node]][v]) swap(u,v); st[node].modify(1,1,times[node],sta[dep[node]][v],fin[dep[node]][v],change); node=up[node]; } return; } void soaking(int u,int t){ int node=u; while(node!=0){ st[node].soak(1,1,times[node],sta[dep[node]][u],t); 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==INF?-1: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; ap[x]^=1; soaking(x,ap[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...