(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 #540712

#TimeUsernameProblemLanguageResultExecution timeMemory
540712jamezzzDynamic Diameter (CEOI19_diameter)C++17
100 / 100
4045 ms229308 KiB
#include <bits/stdc++.h> using namespace std; #ifdef DEBUG #define dbg(...) printf(__VA_ARGS__); #define getchar_unlocked getchar #else #define dbg(...) #endif #define sf scanf #define pf printf #define fi first #define se second #define pb push_back #define sz(x) (int)x.size() #define mnto(x,y) x=min(x,(__typeof__(x))y) #define mxto(x,y) x=max(x,(__typeof__(x))y) #define INF 1023456789 #define LINF 2023456789123456789 #define all(x) x.begin(), x.end() #define disc(x) sort(all(x));x.resize(unique(all(x))-x.begin()); typedef long long ll; typedef long double ld; typedef pair<int,int> ii; typedef pair<ll,int> li; typedef pair<ll, ll> pll; typedef tuple<int, int, int> iii; typedef tuple<int, int, int, int> iiii; typedef vector<int> vi; typedef vector<ii> vii; typedef vector<pll> vll; mt19937 rng(time(0)); #define mod 1000000007 inline int add(int a,int b){ int r=a+b; while(r>=mod)r-=mod; while(r<0)r+=mod; return r; } inline int mult(int a,int b){ return (int)(((ll)(a*b))%mod); } inline int rd(){ int x=0; char ch=getchar_unlocked(); while(!(ch&16))ch=getchar();//keep reading while current character is whitespace while(ch&16){//this will break when ‘\n’ or ‘ ‘ is encountered x=(x<<3)+(x<<1)+(ch&15); ch=getchar_unlocked(); } return x; } #define maxn 100005 struct edge{ int u,v;ll w; vector<int> comp; vector<ii> range; }; struct node{ int s,e;ll ans; vector<li> v; vector<ll> lz; vector<ii> ranges; void init(int i,int l,int r){ v[i]={0,l}; lz[i]=0; if(l==r)return; int m=(l+r)>>1; init(2*i+1,l,m); init(2*i+2,m+1,r); } node(int _s,int _e){ s=_s;e=_e; v.resize(4*(e-s+1)); lz.resize(4*(e-s+1),0); ranges.resize(e-s+1); init(0,s,e); } void ppo(int i,int l,int r){ v[i].fi+=lz[i]; if(l!=r){ lz[2*i+1]+=lz[i]; lz[2*i+2]+=lz[i]; } lz[i]=0; } void up(int i,int l,int r,int x,int y,ll nv){ if(l==x&&r==y){ lz[i]+=nv;return; } int m=(l+r)>>1; if(y<=m)up(2*i+1,l,m,x,y,nv); else if(x>m)up(2*i+2,m+1,r,x,y,nv); else{ up(2*i+1,l,m,x,m,nv); up(2*i+2,m+1,r,m+1,y,nv); } ppo(2*i+1,l,m);ppo(2*i+2,m+1,r); v[i]=max(v[2*i+1],v[2*i+2]); } void up(int x,int y,ll nv){ up(0,s,e,x,y,nv); } void print(int i,int l,int r){ int m=(l+r)>>1; if(l!=r)print(2*i+1,l,m),print(2*i+2,m+1,r); } ll qry(){ ans=v[0].fi+lz[0]; int i=v[0].se; up(ranges[i].fi,ranges[i].se,-LINF); if(v[0].fi+lz[0]>=0)ans+=v[0].fi+lz[0]; up(ranges[i].fi,ranges[i].se,LINF); return ans; } }*root[maxn]; int n,q,sub[maxn];ll w; bool mark[maxn]; vii AL[maxn]; vector<edge> edges; vector<int> nodes; void find_sz(int u,int p){ nodes.pb(u); sub[u]=1; for(auto[v,i]:AL[u]){ if(mark[v]||v==p)continue; find_sz(v,u); sub[u]+=sub[v]; } } int cnt; vii ranges; ii dfs(int u,int p,int c){ ii range={cnt,cnt};++cnt; for(auto[v,i]:AL[u]){ if(mark[v]||v==p)continue; ii res=dfs(v,u,c); edges[i].comp.pb(c); edges[i].range.pb(res); mxto(range.se,res.se); if(p==-1)ranges.pb(res); } return range; } void decomp(int u){ nodes.clear(); find_sz(u,-1); int c=u; for(int x:nodes){ int big=sub[u]-sub[x]; for(auto[v,i]:AL[x]){ if(mark[v])continue; if(sub[v]<sub[x])mxto(big,sub[v]); } if(2*big<=sub[u]){ c=x;break; } } cnt=0; ranges.clear(); dfs(c,-1,c); root[c]=new node(0,cnt-1); for(int i=0;i<sz(ranges);++i){ for(int j=ranges[i].fi;j<=ranges[i].se;++j){ root[c]->ranges[j]=ranges[i]; } } mark[c]=true; for(auto[v,i]:AL[c]){ if(!mark[v])decomp(v); } } int main(){ sf("%d%d%lld",&n,&q,&w); for(int i=0;i<n-1;++i){ int a,b;ll c; sf("%d%d%lld",&a,&b,&c); AL[a].pb({b,i}); AL[b].pb({a,i}); edges.pb({a,b,c,{},{}}); } decomp(1); for(edge &e:edges){ for(int i=0;i<sz(e.comp);++i){ ii rng=e.range[i]; root[e.comp[i]]->up(rng.fi,rng.se,e.w); } } set<li> s; for(int i=1;i<=n;++i){ s.insert({root[i]->qry(),i}); } ll ans=0; while(q--){ ll idx,nw; sf("%lld%lld",&idx,&nw); idx=(idx+ans)%(n-1); nw=(nw+ans)%w; edge &e=edges[idx]; ll ow=e.w; e.w=nw; for(int i=0;i<sz(e.comp);++i){ ii rng=e.range[i]; int c=e.comp[i]; ll old=root[c]->ans; root[c]->up(rng.fi,rng.se,nw-ow); ll upd=root[c]->qry(); s.erase(s.find({old,c})); s.insert({upd,c}); } ans=(*--s.end()).fi; pf("%lld\n",ans); } }

Compilation message (stderr)

diameter.cpp: In function 'int main()':
diameter.cpp:201:4: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  201 |  sf("%d%d%lld",&n,&q,&w);
      |    ^
diameter.cpp:204:5: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  204 |   sf("%d%d%lld",&a,&b,&c);
      |     ^
diameter.cpp:227:5: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  227 |   sf("%lld%lld",&idx,&nw);
      |     ^
#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...