Submission #1095416

#TimeUsernameProblemLanguageResultExecution timeMemory
1095416PieArmyDynamic Diameter (CEOI19_diameter)C++17
49 / 100
5057 ms344416 KiB
typedef long long ll; ll pie(ll army){return (1ll<<army);} #include <bits/stdc++.h> #define fr first #define sc second #define pb push_back #define endl '\n' #define mid ((left+right)>>1) const ll inf=2000000000000000005; const int sonsuz=2000000005; using namespace std; ll fpow(ll x,ll y,ll m=0){if(y<0){cout<<"powError";return -1;}if(m)x%=m;ll res=1;while(y>0){if(y&1)res*=x;x*=x;if(m){x%=m;res%=m;}y>>=1;}return res;} struct Seg{ int n; vector<ll>sum,pref,suf,mx,arr; void build(int node=1,int left=0,int right=-1){ if(right==-1)right=n-1; if(left==right){ sum[node]=arr[left]; mx[node]=pref[node]=suf[node]=max(arr[left],0ll); return; } build(node+1,left,mid);build(node+((mid-left+1)<<1),mid+1,right); sum[node]=sum[node+1]+sum[node+((mid-left+1)<<1)]; pref[node]=max(pref[node+1],sum[node+1]+pref[node+((mid-left+1)<<1)]); suf[node]=max(suf[node+((mid-left+1)<<1)],sum[node+((mid-left+1)<<1)]+suf[node+1]); mx[node]=max(max(mx[node+1],mx[node+((mid-left+1)<<1)]),pref[node+((mid-left+1)<<1)]+suf[node+1]); } void yap(){ n=arr.size(); sum.resize((n<<1)+1); pref.resize((n<<1)+1); suf.resize((n<<1)+1); mx.resize((n<<1)+1); build(); } int tar;ll x; void up(int node=1,int left=0,int right=-1){ if(right==-1)right=n-1; if(left==right){ sum[node]+=x; mx[node]=pref[node]=suf[node]=max(sum[node],0ll); return; } if(tar>mid)up(node+((mid-left+1)<<1),mid+1,right); else up(node+1,left,mid); sum[node]=sum[node+1]+sum[node+((mid-left+1)<<1)]; pref[node]=max(pref[node+1],sum[node+1]+pref[node+((mid-left+1)<<1)]); suf[node]=max(suf[node+((mid-left+1)<<1)],sum[node+((mid-left+1)<<1)]+suf[node+1]); mx[node]=max(max(mx[node+1],mx[node+((mid-left+1)<<1)]),pref[node+((mid-left+1)<<1)]+suf[node+1]); } void update(int a,ll b){ tar=a;x=b; up(); } }; int n,q; ll w,K[100001]; vector<pair<int,ll>>adj[100001]; map<int,pair<int,int>>in_out[100001]; map<int,int>dep[100001]; multiset<ll>vals[100001]; vector<Seg>seg[100001]; int level[100001],par[100001],parnum[100001]; pair<int,int>edge[100001]; multiset<ll>bests; // temp stuff int sub[100001]; int tim,curi,root; // temp stuff void dfs1(int pos,int prev){ sub[pos]=1; for(auto[x,y]:adj[pos]){ if(level[x]==0&&x!=prev){ dfs1(x,pos); sub[pos]+=sub[x]; } } } void dfs2(int pos,int prev,ll l){ seg[root][curi].arr[tim]+=l; in_out[root][pos].fr=tim++; for(auto[x,y]:adj[pos]){ if(level[x])continue; if(x==prev)continue; dep[root][x]=dep[root][pos]+1; dfs2(x,pos,y); } in_out[root][pos].sc=tim; seg[root][curi].arr[tim]-=l; } void cal(int pos,int prev,int num){ dfs1(pos,0); int total=sub[pos]; int paren=pos; while(true){ int nex=0; for(auto[x,y]:adj[pos]){ if(level[x]!=0||x==paren)continue; if(sub[x]>(total>>1)){ nex=x; break; } } if(!nex)break; paren=pos; pos=nex; } par[pos]=prev; parnum[pos]=num; level[pos]=level[par[pos]]+1; seg[pos].resize(adj[pos].size()); vals[pos].insert(0); vals[pos].insert(0); root=pos; for(int i=0;i<adj[pos].size();i++){ if(level[adj[pos][i].fr])continue; seg[pos][i].arr.resize(adj[pos][i].fr==paren?total-sub[pos]+1:sub[adj[pos][i].fr]+1,0); dep[pos][adj[pos][i].fr]=1; tim=0; curi=i; dfs2(adj[pos][i].fr,pos,adj[pos][i].sc); seg[pos][i].yap(); vals[pos].insert(-seg[pos][i].mx[1]); } ll topla=-(*vals[pos].begin())-(*(++vals[pos].begin())); bests.insert(topla); for(int i=0;i<adj[pos].size();i++){ if(level[adj[pos][i].fr])continue; cal(adj[pos][i].fr,pos,i); } } void code(){ cin>>n>>q>>w; for(int i=0;i<n-1;i++){ int a,b;ll c; cin>>a>>b>>c; K[i]=c; edge[i]={a,b}; adj[a].pb({b,c}); adj[b].pb({a,c}); } cal(1,0,0); ll ans=0; while(q--){ int d;ll e; cin>>d>>e; d=(d+ans)%(n-1); e=(e+ans)%w; if(level[edge[d].fr]>level[edge[d].sc])swap(edge[d].fr,edge[d].sc); int pos=edge[d].fr; int sira; int pos2=edge[d].sc; while(pos2!=pos){ sira=parnum[pos2]; pos2=par[pos2]; } while(pos){ ll topla=-(*vals[pos].begin())-(*(++vals[pos].begin())); bests.erase(bests.find(topla)); vals[pos].erase(vals[pos].find(-seg[pos][sira].mx[1])); int cur=edge[d].fr; if(dep[pos][cur]<dep[pos][edge[d].sc])cur=edge[d].sc; seg[pos][sira].update(in_out[pos][cur].fr,e-K[d]); seg[pos][sira].update(in_out[pos][cur].sc,K[d]-e); vals[pos].insert(-seg[pos][sira].mx[1]); topla=-(*vals[pos].begin())-(*(++vals[pos].begin())); bests.insert(topla); sira=parnum[pos]; pos=par[pos]; } K[d]=e; ans=*(--bests.end()); cout<<ans<<endl; } } int main(){ ios_base::sync_with_stdio(false);cin.tie(NULL); bool usaco=0;if(usaco){freopen(".in","r",stdin);freopen(".out","w",stdout);} int t=1; if(!t)cin>>t; while(t--){code();} return 0; }

Compilation message (stderr)

diameter.cpp: In function 'void cal(int, int, int)':
diameter.cpp:121:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  121 |  for(int i=0;i<adj[pos].size();i++){
      |              ~^~~~~~~~~~~~~~~~
diameter.cpp:133:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  133 |  for(int i=0;i<adj[pos].size();i++){
      |              ~^~~~~~~~~~~~~~~~
diameter.cpp: In function 'int main()':
diameter.cpp:186:32: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  186 |  bool usaco=0;if(usaco){freopen(".in","r",stdin);freopen(".out","w",stdout);}
      |                         ~~~~~~~^~~~~~~~~~~~~~~~~
diameter.cpp:186:57: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  186 |  bool usaco=0;if(usaco){freopen(".in","r",stdin);freopen(".out","w",stdout);}
      |                                                  ~~~~~~~^~~~~~~~~~~~~~~~~~~
diameter.cpp: In function 'void code()':
diameter.cpp:167:49: warning: 'sira' may be used uninitialized in this function [-Wmaybe-uninitialized]
  167 |    vals[pos].erase(vals[pos].find(-seg[pos][sira].mx[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...