제출 #1325488

#제출 시각아이디문제언어결과실행 시간메모리
1325488boclobanchatDynamic Diameter (CEOI19_diameter)C++20
100 / 100
2277 ms205144 KiB
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
namespace st
{
	pair<long long,long long> seg[MAXN*67];
	int L[MAXN*67],R[MAXN*67],root[MAXN*67],F[MAXN*67],cnt=0;
	void build(int l,int r,int pos)
	{
		if(l==r)
		{
			F[l+cnt]=pos+cnt;
			return ;
		}
		int mid=(l+r)/2;
		root[pos*2+cnt]=pos+cnt;
		root[pos*2+cnt+1]=pos+cnt;
		L[pos+cnt]=pos*2+cnt;
		R[pos+cnt]=pos*2+cnt+1;
		build(l,mid,pos*2);
		build(mid+1,r,pos*2+1);
	}
	long long update(int idx,long long val)
	{
		idx=F[idx];
		if(!idx) return 0;
		seg[idx].first+=val,seg[idx].second+=val;
		while(root[idx])
		{
			idx=root[idx];
			seg[idx].first=seg[L[idx]].first+seg[R[idx]].first;
			seg[idx].second=max(seg[L[idx]].second,seg[L[idx]].first+seg[R[idx]].second);
		}
		return seg[idx].second;
	}
}
struct edge
{
	long long nex,pos,val;
};
struct query
{
	int p,l,r;
};
vector<edge> ds[MAXN];
vector<query> vq[MAXN];
long long len[MAXN],edge[MAXN],F[MAXN],seg[MAXN*4];
int sub[MAXN],L[MAXN],R[MAXN],rt[MAXN],tdfs=0,cnt=0,cp=0;
bool ck[MAXN];
set< pair<long long,int> > val[MAXN];
void update(int l,int r,int i,long long val,int pos)
{
	if(i<l||r<i) return ;
	if(l==r)
	{
		seg[pos]=val;
		return ;
	}
	int mid=(l+r)/2;
	update(l,mid,i,val,pos*2);
	update(mid+1,r,i,val,pos*2+1);
	seg[pos]=max(seg[pos*2],seg[pos*2+1]);
}
void dfs(int i,int pre)
{
	sub[i]=1;
	for(auto v:ds[i]) if(v.nex!=pre&&!ck[v.nex])
	{
		dfs(v.nex,i);
		sub[i]+=sub[v.nex];
	}
}
void dfs2(int i,int pre,int root)
{
	L[i]=++tdfs;
	for(auto v:ds[i]) if(v.nex!=pre&&!ck[v.nex])
	{
		if(i==pre)
		{
			tdfs=0;
			dfs2(v.nex,i,++cnt);
			st::build(1,tdfs,1);
			rt[cnt]=i,val[i].insert({0,cnt});
			vq[v.pos].push_back({cnt,L[v.nex]+cp,R[v.nex]+cp});
			cp+=tdfs*4,st::cnt+=tdfs*4;
		}
		else
		{
			dfs2(v.nex,i,root);
			vq[v.pos].push_back({root,L[v.nex]+cp,R[v.nex]+cp});
		}
	}
	R[i]=tdfs;
}
int centroid(int i,int pre,int cnt)
{
	for(auto v:ds[i]) if(v.nex!=pre&&!ck[v.nex]&&sub[v.nex]*2>cnt) return centroid(v.nex,i,cnt);
	return i;
}
void decomp(int i)
{
	dfs(i,i);
	int pos=centroid(i,i,sub[i]);
	ck[pos]=true;
	dfs2(pos,pos,0);
	for(auto v:ds[pos]) if(!ck[v.nex]) decomp(v.nex);
}
void update(int i,int n,long long w)
{
	w-=edge[i];
	for(auto v:vq[i])
	{
		val[rt[v.p]].erase({F[v.p],v.p});
		st::update(v.r+1,-w);
		val[rt[v.p]].insert({F[v.p]=(st::update(v.l,w)),v.p});
		auto res=prev(val[rt[v.p]].end());
		if(res==val[rt[v.p]].begin()) update(1,n,rt[v.p],(*res).first,1);
		else update(1,n,rt[v.p],(*res).first+(*prev(res)).first,1);
	}
	edge[i]+=w;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,q;
	long long w;
	cin>>n>>q>>w;
	for(int i=1;i<n;i++)
	{
		long long l,r,v;
		cin>>l>>r>>v;
		len[i]=v;
		ds[l].push_back({r,i,v}),ds[r].push_back({l,i,v});
	}
	decomp(1);
	for(int i=1;i<n;i++) update(i,n,len[i]);
	long long last=0;
	for(int i=1;i<=q;i++)
	{
		long long d,e;
		cin>>d>>e;
		d=(d+last)%(n-1),e=(e+last)%w;
		update(d+1,n,e);
		cout<<(last=seg[1])<<"\n";
	}
}
#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...