题意:给一棵带边权的树,多次询问$(x,y,l)$表示如果加一条连接$x$和$y$的长为$l$的边,所有点到$x$和到$y$的最短路减少了多少

先把题目中的图放上来(雾

考虑用lct维护,先把路径提出来,然后在splay上二分找到最短路大小改变的临界点$p$,再统计答案

容易看出$p\rightarrow y$上的所有点的子树都对答案有贡献,对于一个点$p_1$,它和它的虚子树对答案的贡献都是$dis_{x,p_1}-dis_{p_1,y}-l$,即$dis_{x,y}-2dis_{p_1,y}-l$,于是我们可以维护每个点在splay中往左往右的答案(因为要换根,有区间翻转操作),再维护一下虚子树大小即可

车万题吼啊!

#include<stdio.h>
#include<string.h>
typedef long long ll;
template<class C>void swap(C&a,C&b){a^=b^=a^=b;}
int ch[100010][2],fa[100010],r[100010],siz[100010],vsiz[100010];
ll lsum[100010],rsum[100010],s[100010],v[100010];
#define ls ch[x][0]
#define rs ch[x][1]
void rev(int x){
	r[x]^=1;
	swap(ls,rs);
	swap(lsum[x],rsum[x]);
}
void pushdown(int x){
	if(r[x]){
		if(ls)rev(ls);
		if(rs)rev(rs);
		r[x]=0;
	}
}
void pushup(int x){
	siz[x]=siz[ls]+siz[rs]+vsiz[x];
	s[x]=s[ls]+s[rs]+v[x];
	lsum[x]=lsum[ls]+lsum[rs]+(s[ls]+v[x])*siz[rs]+vsiz[x]*s[ls];
	rsum[x]=rsum[ls]+rsum[rs]+(s[rs]+v[x])*siz[ls]+vsiz[x]*s[rs];
}
void rot(int x){
	int y,z,f,b;
	y=fa[x];
	z=fa[y];
	f=ch[y][0]==x;
	b=ch[x][f];
	fa[x]=z;
	fa[y]=x;
	if(b)fa[b]=y;
	ch[x][f]=y;
	ch[y][f^1]=b;
	if(ch[z][0]==y)ch[z][0]=x;
	if(ch[z][1]==y)ch[z][1]=x;
	pushup(y);
	pushup(x);
}
bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void gao(int x){
	if(!isrt(x))gao(fa[x]);
	pushdown(x);
}
void splay(int x){
	gao(x);
	int y,z;
	while(!isrt(x)){
		y=fa[x];
		z=fa[y];
		if(!isrt(y))rot((ch[z][0]==y&&ch[y][0]==x)||(ch[z][1]==y&&ch[y][1]==x)?y:x);
		rot(x);
	}
}
void access(int x){
	int y=0;
	while(x){
		splay(x);
		vsiz[x]+=siz[rs];
		rs=y;
		vsiz[x]-=siz[y];
		pushup(x);
		y=x;
		x=fa[x];
	}
}
void makert(int x){
	access(x);
	splay(x);
	rev(x);
}
int find(int x,ll d){
	int c=0;
	ll al=s[x];
	while(x){
		pushdown(x);
		if((s[ls]+v[x])*2<=al+d){
			c=x;
			d-=(s[ls]+v[x])*2;
			x=rs;
		}else
			x=ls;
	}
	return c;
}
ll query(int x,int y,ll z){
	if(x==y)return 0;
	makert(x);
	access(y);
	splay(y);
	if(s[y]<=z)return 0;
	x=find(y,z);
	splay(x);
	return siz[rs]*(s[x]-z)-rsum[rs]*2;
}
int h[100010],nex[200010],to[200010],M;
void add(int a,int b){
	M++;
	to[M]=b;
	nex[M]=h[a];
	h[a]=M;
}
void dfs(int x){
	for(int i=h[x];i;i=nex[i]){
		if(to[i]!=fa[x]){
			fa[to[i]]=x;
			dfs(to[i]);
			siz[x]+=siz[to[i]];
		}
	}
	vsiz[x]=siz[x];
}
int main(){
	int n,m,i,x,y,z;
	while(~scanf("%d",&n)){
		memset(h,0,sizeof(h));
		memset(fa,0,sizeof(fa));
		memset(ch,0,sizeof(ch));
		memset(siz,0,sizeof(siz));
		memset(r,0,sizeof(r));
		memset(lsum,0,sizeof(lsum));
		memset(rsum,0,sizeof(rsum));
		memset(s,0,sizeof(s));
		memset(v,0,sizeof(v));
		M=0;
		for(i=1;i<=n;i++)siz[i]=1;
		for(i=1;i<n;i++){
			scanf("%d%d%d",&x,&y,&z);
			v[n+i]=s[n+i]=z;
			add(x,n+i);
			add(n+i,x);
			add(y,n+i);
			add(n+i,y);
		}
		dfs(1);
		scanf("%d",&m);
		while(m--){
			scanf("%d%d%d",&x,&y,&z);
			printf("%lld\n",query(x,y,z)+query(y,x,z));
		}
	}
}

[ZOJ3522]Hide and seek的更多相关文章

  1. 【BZOJ-1941】Hide and Seek KD-Tree

    1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 830  Solved: 455[Submi ...

  2. [BZOJ1941][Sdoi2010]Hide and Seek

    [BZOJ1941][Sdoi2010]Hide and Seek 试题描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他 ...

  3. BZOJ3402: [Usaco2009 Open]Hide and Seek 捉迷藏

    3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 51  Solved: 4 ...

  4. BZOJ 3402: [Usaco2009 Open]Hide and Seek 捉迷藏

    题目 3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MB Description     贝 ...

  5. 3402: [Usaco2009 Open]Hide and Seek 捉迷藏

    3402: [Usaco2009 Open]Hide and Seek 捉迷藏 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 78  Solved: 6 ...

  6. bzoj:1941: [Sdoi2010]Hide and Seek

    1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec  Memory Limit: 162 MBSubmit: 531  Solved: 295[Submi ...

  7. 【BZOJ】【1941】【SDOI2010】Hide and Seek

    KD-Tree 一开始看错题了

  8. 洛谷 P2951 [USACO09OPEN]捉迷藏Hide and Seek

    题目戳 题目描述 Bessie is playing hide and seek (a game in which a number of players hide and a single play ...

  9. 【BZOJ1941】Hide and Seek(KD-Tree)

    [BZOJ1941]Hide and Seek(KD-Tree) 题面 BZOJ 洛谷 题解 \(KD-Tree\)对于每个点搜一下最近点和最远点就好了 #include<iostream> ...

随机推荐

  1. Android开发注意点小记

    暂时主要讨论以下几点: Android引用外部包,报NoClassDefFoundError异常崩溃 同名包引用关系问题 程序图标 9patch图片素材 Android引用外部包,程序报java.la ...

  2. The 13th Zhejiang Provincial Collegiate Programming Contest - C

    Defuse the Bomb Time Limit: 2 Seconds      Memory Limit: 65536 KB The bomb is about to explode! Plea ...

  3. NOIP2016愤怒的小鸟 [状压dp]

    愤怒的小鸟 题目描述 Kiana 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 (0,0) 处,每次 Kiana 可以用它向第一象限发射一只红色的小鸟, ...

  4. ionic3自定义图标

    http://blog.csdn.net/qq993284758/article/details/78107412

  5. HDFS集中化缓存管理

    概述 HDFS中的集中化缓存管理是一个明确的缓存机制,它允许用户指定要缓存的HDFS路径.NameNode会和保存着所需快数据的所有DataNode通信,并指导他们把块数据缓存在off-heap缓存中 ...

  6. [05]Git查看、删除、重命名远程分支和tag

    Git查看.删除.重命名远程分支和tag 2015-06-15:加入姊妹篇: 2013-11-06:加入重命名远程分支的内容: 2013-01-09:加入删除远程tag的内容. 姊妹篇:使用Git.G ...

  7. UITableView学习之辨析两个方法:⓵dequeueReusableCellWithIdentifier与⓶dequeueReusableCellWithIdentifier:forIndexPath:

    使用storyboard显示UITableView时,如果不修改系统默认生成的tableView:cellForRowAtIndexPath:方法中的代码,必须为UITableViewCell注册(填 ...

  8. System and method for parallel execution of memory transactions using multiple memory models, including SSO, TSO, PSO and RMO

    A data processor supports the use of multiple memory models by computer programs. At a device extern ...

  9. Linux c括号作用域【原创笔记】

    大师指点后,所做的笔记,很感谢一起愿意研究技术的同事,以下不是本人原创,是他分析的成果 #include <stdio.h> #include <time.h> struct ...

  10. appium===安卓SDK下载很慢的解决办法

    方法一:http://www.apkbus.com/forum.php?mod=viewthread&tid=240851 方法二:http://www.androiddevtools.cn/