(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

Submission #1098790

#TimeUsernameProblemLanguageResultExecution timeMemory
1098790damwuanDynamic Diameter (CEOI19_diameter)C++17
100 / 100
2865 ms351420 KiB
#include<bits/stdc++.h> using namespace std; #define int ll #define fi first #define se second #define pb push_back #define all(x) x.begin(),x.end() #define for1(i,x,n) for(int i=x;i<=n;i++) #define for2(i,x,n) for(int i=x;i>=n;i--) typedef long long ll; typedef pair<int,int> pii; const ll maxn = 1e5 + 3; const ll mod = 1e9 + 7; const ll inf = 1e18; int n,q; int mx[maxn*4]; int sz[maxn],dep[maxn],in[maxn],out[maxn],Time,uu[maxn],vv[maxn],w[maxn],a[maxn],b[maxn],k[maxn],ans[maxn]; bool used[maxn],dd[maxn]; vector<int> adj[maxn],qr[maxn],go[maxn]; void Udp(int u,int v,int id=1,int l=1,int r=n) { if (l==r) { mx[id]=v; return; } int mid=l+r>>1; if (u<=mid) Udp(u,v,id*2,l,mid); else Udp(u,v,id*2+1,mid+1,r); mx[id]=max(mx[id*2],mx[id*2+1]); } struct T { int cen,up,dep,in,out; }; vector<T> L[maxn]; struct Node { pii x, y; }; Node Merge(Node a,Node b) { if (a.x<b.x) swap(a,b); if (a.x.se!=b.x.se) a.y=max(a.y,b.x); if (a.x.se!=b.y.se) a.y=max(a.y,b.y); return a; } struct segtree { int nn; vector<Node> st; vector<int> lazy; void init(int x) { nn=x; st.resize(nn*4+2,(Node){{-1,-1},{-1,-1}}); lazy.resize(nn*4+2,0); } void push(int id) { int& val=lazy[id]; if (st[id*2].x.fi!=-1) st[id*2].x.fi+=val; if (st[id*2].y.fi!=-1) st[id*2].y.fi+=val; lazy[id*2]+=val; if (st[id*2+1].x.fi!=-1) st[id*2+1].x.fi+=val; if (st[id*2+1].y.fi!=-1) st[id*2+1].y.fi+=val; lazy[id*2+1]+=val; val=0; } void Update(int u,pii v,int id,int l,int r) { if (l==r) { st[id]={v,{-1,-1}}; return; } if (lazy[id]) push(id); int mid=l+r>>1; if (u<=mid) Update(u,v,id*2,l,mid); else Update(u,v,id*2+1,mid+1,r); st[id]=Merge(st[id*2],st[id*2+1]); } void Update2(int u,int v,int val,int id,int l,int r) { if (u>r || v<l) return; if (u<=l && r<=v) { if (st[id].x.fi!=-1) st[id].x.fi+=val; if (st[id].y.fi!=-1) st[id].y.fi+=val; lazy[id]+=val; return; } if (lazy[id]) push(id); int mid=l+r>>1; Update2(u,v,val,id*2,l,mid); Update2(u,v,val,id*2+1,mid+1,r); st[id]=Merge(st[id*2],st[id*2+1]); } }tree[maxn]; void dfs_sz(int u,int pre) { sz[u]=1; for(int i: adj[u]) { int v=u^uu[i]^vv[i]; if (v==pre || used[v]) continue; dfs_sz(v,u); sz[u]+=sz[v]; } } int Find_cen(int u,int pre,int treesz) { for(int i:adj[u]) { int v=u^uu[i]^vv[i]; if (v==pre || used[v]) continue; if (sz[v]*2>treesz) return Find_cen(v,u,treesz); } return u; } void dfs_dep(int u,int pre) { for(int i: adj[u]) { int v=u^uu[i]^vv[i]; if (v==pre || used[v]) continue; dep[v]=dep[u]+w[i]; // cerr<<" d "<<v<<' '<< dep[v]<<'\n'; dfs_dep(v,u); } } void initial(int u,int pre,int cen,int rt) { in[u]=++Time; for(int i: adj[u]) { int v=u^uu[i]^vv[i]; if (v==pre || used[v]) continue; initial(v,u,cen,rt); } out[u]=Time; L[u].pb({cen,rt,dep[u],in[u],out[u]}); } void centroid(int u) { dfs_sz(u,-1); if (sz[u]==1) return; // cerr<< sz[u]<<'\n'; u=Find_cen(u,-1,sz[u]); // cerr<<"cen "<< u<<"\n"; used[u]=1; dep[u]=0; dfs_dep(u,-1); Time=1; for(int i:adj[u]) { int v=u^uu[i]^vv[i]; if (used[v]) continue; initial(v,u,u,v); } L[u].pb({u,u,0,1,Time}); tree[u].init(Time); for(int i: adj[u]) { int v=u^uu[i]^vv[i]; if (used[v]) continue; centroid(v); } } void Add(int u) { // cerr<< "add dinh "<<u<<' '<<L[u].size()<<'\n'; for(auto x:L[u]) { // cerr<< x.cen<<' '<<x.up<<' '<< x.dep<<'\n'; tree[x.cen].Update(x.in,{x.dep,x.up},1,1,tree[x.cen].nn); if (tree[x.cen].st[1].y.fi!=-1) Udp(x.cen,tree[x.cen].st[1].x.fi+tree[x.cen].st[1].y.fi); } // cerr<<tree[2].st[1].x.fi<<' '<<tree[2].st[1].y.fi<<'\n'; } void sol() { int WW; cin >> n>> q>>WW; for1(i,1,n-1) { cin >> uu[i]>>vv[i]>>w[i]; adj[uu[i]].pb(i); adj[vv[i]].pb(i); } centroid(1); for1(i,1,n) Add(i); int last=0,d=0,e=0; for1(i,1,q) { cin >> d>>e; d=(d+last)%(n-1); e=(e+last)%WW; int j=d+1; for(auto x: L[uu[j]]) { for(auto y:L[vv[j]]) { if (x.cen==y.cen) { T g; if (x.in<y.in) g=y; else g=x; tree[g.cen].Update2(g.in,g.out,e-w[j],1,1,tree[x.cen].nn); if (tree[x.cen].st[1].y.fi!=-1) Udp(x.cen,tree[x.cen].st[1].x.fi+tree[x.cen].st[1].y.fi); } } } w[j]=e; last=mx[1]; cout << last<<'\n'; } } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int t=1;//cin >> t; while (t--) sol(); } /* 5 5 3 5 3 5 10 1 20 1 20 */

Compilation message (stderr)

diameter.cpp: In function 'void Udp(ll, ll, ll, ll, ll)':
diameter.cpp:30:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   30 |     int mid=l+r>>1;
      |             ~^~
diameter.cpp: In member function 'void segtree::Update(ll, pii, ll, ll, ll)':
diameter.cpp:85:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   85 |         int mid=l+r>>1;
      |                 ~^~
diameter.cpp: In member function 'void segtree::Update2(ll, ll, ll, ll, ll, ll)':
diameter.cpp:101:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  101 |         int mid=l+r>>1;
      |                 ~^~
#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...