LuoguAC,本地RE???
查看原帖
LuoguAC,本地RE???
190322
Varuxn楼主2021/6/14 08:38

记录

#include<bits/stdc++.h>
#define int long long
#define f() cout<<"fu*ck"<<endl
using namespace std;
const int N=1e5+10;
const int M=N<<1;
int n,m,tot,S,root,s[N],siz[N],rt[N],dep[N],w[N];
int edg_tot,ver[M],head[N],nxt[M],edge[M];
bool vis[N];
vector<pair<int ,int > > son[N],f[N];
inline void add_edge(int x,int y,int val)
{
	ver[++edg_tot]=y;
	edge[edg_tot]=val;
	nxt[edg_tot]=head[x];
	head[x]=edg_tot;
}
inline void get_size(int x,int fa)
{
//	cout<<"Size:      "<<x<<' '<<fa<<endl;
	siz[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
	 	int to=ver[i];
		if(to==fa||vis[to])
			continue;
		get_size(to,x);
		siz[x]+=siz[to];
	}
}
inline void get_root(int x,int fa)
{
//	cout<<"Root:     "<<x<<' '<<fa<<endl;
	root=x;
	for(int i=head[x];i;i=nxt[i])
	{
		int to=ver[i];
		if(vis[to]||to==fa||siz[to]*2<S)
			continue;
		get_root(to,x);
		break;
	}
}
inline void dfs(int x,int fa,int top)
{
//	cout<<"Dfs:      "<<x<<' '<<fa<<' '<<top<<endl;
	f[x].push_back(make_pair(top,dep[x]));
	for(int i=head[x];i;i=nxt[i])
	{
		int to=ver[i],val=edge[i];
		if(vis[to]||to==fa)
			continue;
		dep[to]=dep[x]+val;
		dfs(to,x,top);
	}
}
inline void init_work(int x,int fa)
{
//	cout<<"Init:      "<<x<<' '<<fa<<endl;
	get_size(x,fa);
	S=siz[x];
	get_root(x,fa);
	vis[root]=true;
	int temp=root;
	f[temp].push_back(make_pair(temp,0ll));
	son[fa].push_back(make_pair(temp,0ll));
	rt[temp]=x;
	for(int i=head[root];i;i=nxt[i])
	{
		int to=ver[i],val=edge[i];
		if(vis[to])
			continue;
		dep[to]=val;
		dfs(to,temp,temp);
		init_work(to,temp);
	}
	root=temp;
}
inline void insert(int x,int val)
{
//	cout<<"Insert:     "<<x<<' '<<val<<endl;
	tot+=val;
	s[x]+=val;
	for(int i=f[x].size()-1;i>=0;i--)
		w[f[x][i].first]+=val;
	for(int i=f[x].size()-2;i>=0;i--)
		for(int j=son[f[x][i].first].size()-1;j>=0;j--)
			if(son[f[x][i].first][j].first==f[x][i+1].first)
			{
				son[f[x][i].first][j].second+=val*f[x][i].second;
				break;
			}
}
inline void update(int x,int val)
{
//	cout<<"Update:       "<<x<<' '<<val<<endl;
	for(int i=f[x].size()-1;i>=0;i--)
		w[f[x][i].first]+=val;
}
inline int find(int x)
{
//	cout<<"Find:     "<<x<<endl;
	int ret=x;
	for(int i=son[x].size()-1;i>=0;i--)
		if(w[son[x][i].first]*2>=tot)
		{
//			f();
			int temp=w[x]-w[son[x][i].first];
			update(rt[son[x][i].first],temp);
//			f();
			ret=find(son[x][i].first);
//			f();
			update(rt[son[x][i].first],-temp);
//			cout<<temp<<' '<<ret<<endl;
			break;
		}
	return ret;
}
inline int query(int x)
{
//	cout<<"Query:     "<<x<<endl;
	int ret=0,las=0;
	for(int i=f[x].size()-1;i>=0;las=f[x][i].first,i--)
	{
		ret+=f[x][i].second*s[f[x][i].first];
		for(int j=son[f[x][i].first].size()-1;j>=0;j--)
			if(son[f[x][i].first][j].first!=las)
				ret+=f[x][i].second*w[son[f[x][i].first][j].first]+son[f[x][i].first][j].second;
	}
	return ret;
}
void check()
{
	cout<<"Father:     "<<endl;
	for(int i=1;i<=n;i++)
	{
		cout<<"I="<<i<<":          ";
		for(int j=0;j<f[i].size();j++)
			cout<<"("<<f[i][j].first<<','<<f[i][j].second<<")    ";
		cout<<endl;
	}
	cout<<"Son:     "<<endl;
	for(int i=1;i<=n;i++)
	{
		cout<<"I="<<i<<":          ";
		for(int j=0;j<son[i].size();j++)
			cout<<"("<<son[i][j].first<<','<<son[i][j].second<<")    ";
		cout<<endl;
	}
}
#undef int
int main()
{
	#define int register long long
	#define ll long long
	scanf("%lld%lld",&n,&m);
	for(int i=1,x,y,val;i<n;i++)
	{
		scanf("%lld%lld%lld",&x,&y,&val);
		add_edge(x,y,val);
		add_edge(y,x,val);
	}
	init_work(1,0);
//	for(int i=1;i<=n;i++)	cout<<siz[i]<<' ';
//	check();
	while(m--)
	{
		int x,val;
		scanf("%lld%lld",&x,&val);
		insert(x,val);
		printf("%lld\n",query(find(root)));
	}
	return 0;
}
/*
Luogu P3345 [ZJOI2015]幻想乡战略游戏
Created by Varuxn
On 2021.6.14
*/
2021/6/14 08:38
加载中...