记录编号 477891 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [ZJOI 2015] 幻想乡战略游戏 最终得分 100
用户昵称 GravatarLadyLex 是否通过 通过
代码语言 C++ 运行时间 15.316 s
提交时间 2017-12-07 19:20:17 内存使用 24.83 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
#define N 100010
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
struct edge{int zhong,next,val;};
struct G
{
	edge s[N<<1];int e,adj[N];
	G(){e=0;memset(adj,0,sizeof(adj));}
	inline void add(int qi,int zhong,int val=0)
		{s[++e].zhong=zhong;s[e].next=adj[qi];adj[qi]=e;s[e].val=val;}
}T1,T2;
int n,q,f[N<<1][18],logn[N<<1],bin[25],tp;
LL s[3][N],sum,ans,len[N];
int dfn[N],num;
inline void dfs1(int rt,int fa)
{
	f[(dfn[rt]=++num)][0]=len[rt];
	for(int i=T1.adj[rt];i;i=T1.s[i].next)
		if(T1.s[i].zhong!=fa)
			len[T1.s[i].zhong]=len[rt]+T1.s[i].val,dfs1(T1.s[i].zhong,rt),f[++num][0]=len[rt];
}
inline LL LCA(int a,int b)
{
	if(dfn[a]>dfn[b])a^=b,b^=a,a^=b;
	int k=logn[dfn[b]-dfn[a]+1];
	return min(f[dfn[a]][k],f[dfn[b]-bin[k]+1][k])<<1;
}
inline LL dis(int a,int b){return len[a]+len[b]-LCA(a,b);}
int size[N],maxs[N],totsize,root,Vater[N];
bool vis[N];
inline void dfs2(int rt,int fa)
{
	size[rt]=1,maxs[rt]=0;
	for(int i=T1.adj[rt];i;i=T1.s[i].next)
		if(!vis[T1.s[i].zhong]&&T1.s[i].zhong!=fa)
			dfs2(T1.s[i].zhong,rt),size[rt]+=size[T1.s[i].zhong],
			maxs[rt]=max(size[T1.s[i].zhong],maxs[rt]);
	maxs[rt]=max(totsize-size[rt],maxs[rt]);
	if(maxs[rt]<maxs[root])root=rt;
}
inline void dfs3(int rt,int fa)
{
	Vater[rt]=fa;vis[rt]=1;int siz=totsize;
	for(int i=T1.adj[rt];i;i=T1.s[i].next)
		if(!vis[T1.s[i].zhong])
		{
			if(size[T1.s[i].zhong]>size[rt])totsize=siz-size[rt];
			else totsize=size[T1.s[i].zhong];
			root=0,dfs2(T1.s[i].zhong,0),T2.add(rt,root,T1.s[i].zhong),dfs3(root,rt);
		}
}
inline void update(int who,LL val)
{
	for(int rt=who;rt;rt=Vater[rt])
	{
		s[0][rt]+=val,s[1][rt]+=dis(rt,who)*val;
		if(Vater[rt])s[2][rt]+=dis(Vater[rt],who)*val;
	}
}
inline LL calc(int rt)
{
	LL ret=0;
	for(int x=rt;x;x=Vater[x])
	{
		ret+=s[1][x];
		if(Vater[x])ret+=-s[2][x]+(s[0][Vater[x]]-s[0][x])*dis(Vater[x],rt);
	}
	return ret;
}
inline LL getans(int rt)
{
	LL temp=calc(rt);
	for(int i=T2.adj[rt];i;i=T2.s[i].next)
		if(calc(T2.s[i].val)<temp)return getans(T2.s[i].zhong);//*******
	return temp;
}
char B[1<<15],*S=B,*T=B;
#define getc ( S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
inline int read()
{
	int x=0,f=1;register char c=getc;
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getc;}
	while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
	return x*f;
}
int main()
{
	freopen("zjoi15_tree.in","r",stdin);
	freopen("zjoi15_tree.out","w",stdout);
	// freopen("Ark.in","r",stdin);
	register int i,j,orig,a,b,c;
	n=read();q=read();
	for(bin[0]=i=1;i<=20;++i)bin[i]=bin[i-1]<<1;
	while(bin[tp+1]<=(n<<1))++tp;
	for(logn[0]=-1,i=1;i<=(n<<1);++i)logn[i]=logn[i>>1]+1;
	for(i=1;i<n;++i)
		a=read(),b=read(),c=read(),T1.add(a,b,c),T1.add(b,a,c);
	dfs1(1,0),root=0,maxs[0]=n+1,totsize=n,dfs2(1,0);
	for(i=1;i<=tp;++i)
		for(j=1;j+bin[i]-1<=(n<<1);++j)
			f[j][i]=min(f[j][i-1],f[j+bin[i-1]][i-1]);
	orig=root,dfs3(root,0);
	while(q--)
		a=read(),b=read(),update(a,b),printf("%lld\n",getans(orig));
}