洛谷 P2590 BZOJ 1036 [ZJOI2008]树的统计
Time limit 10000 ms//另外,BZOJ只算所有点的总时限,所以可能会放过一些原本会TLE的代码
Memory limit 165888 kB
OS Linux
SourceZJOI2008
吐槽
时隔两年再次写树剖,跟楞半岛,找bug找得想吐,被卡题惨烈程度堪比这次——[HAOI2015]树上操作。
这题被卡的地方在于,单点修改的时候,树上节点的老id没有变成新id,就拿到线段树上做修改了……卡了两天,拿lemon在本地一遍又一遍测试,没有去oj上交,不然有卡评测的嫌疑……
顺便,win10下栈空间好小,4号点、7号点、9号点树比较深,甚至是链,于是win10下跑dfs就给爆栈了,甚至加了#pragma comment(linker,"/STACK:1024000000,1024000000") 也不行(权限不够?)。
这篇博客纯属纪念。
板子题没有解题思路
源代码
#include<cstdio>
#include<algorithm>
int n,q;
struct Edge{
	int nxt,to;
}e[60010];
int head[30010],cnt=1;
void add(int u,int v)
{
	e[cnt]={head[u],v};
	head[u]=cnt++;
	e[cnt]={head[v],u};
	head[v]=cnt++;
}
struct Tree{
	long long w;
	int fa,dep,sz,wson,top,id;
}t[30010];
void dfs1(int u,int fa)
{
	t[u].fa=fa;
	t[u].dep=t[fa].dep+1;
	t[u].sz=1;
	t[u].wson=0;
	int maxn=0;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==fa) continue;
		dfs1(v,u);
		int temp=t[v].sz;
		t[u].sz+=temp;
		if(temp>maxn)
		{
			t[u].wson=v;
			maxn=temp;
		}
	}
}
int id=1;
long long a[30010];
void dfs2(int u,int top)
{
	t[u].top=top;
	t[u].id=id;
	a[id]=t[u].w;
	id++;
	if(!t[u].wson) return;
	dfs2(t[u].wson,top);
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(v==t[u].fa||v==t[u].wson) continue;
		dfs2(v,v);
	}
}
struct SegTree{
	int l,r;
	long long sum,mx;
}s[120010];
inline void pushup(int x)
{
	s[x].sum=s[x<<1].sum+s[x<<1|1].sum;
	s[x].mx=std::max(s[x<<1].mx,s[x<<1|1].mx);
}
void build(int x,int l,int r)
{
	s[x].l=l;
	s[x].r=r;
	if(l==r)
	{
		s[x].mx=s[x].sum=a[l];
		return;
	}
	int mid=l+r>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	pushup(x);
}
void update(int x,int pos,long long k)
{
	if(s[x].l==s[x].r&&s[x].l==pos)
	{
		s[x].mx=s[x].sum=k;
		return;
	}
	int mid=s[x].l+s[x].r>>1;
	if(pos<=mid) update(x<<1,pos,k);
	else update(x<<1|1,pos,k);
	pushup(x);
}
long long quemx(int x,int l,int r)
{
	if(l<=s[x].l&&s[x].r<=r) return s[x].mx;
	int mid=s[x].l+s[x].r>>1;
	long long ans=-1e9;
	if(l<=mid) ans=std::max(ans,quemx(x<<1,l,r));
	if(r>mid) ans=std::max(ans,quemx(x<<1|1,l,r));
	return ans;
}
long long quesum(int x,int l,int r)
{
	if(l<=s[x].l&&s[x].r<=r) return s[x].sum;
	int mid=s[x].l+s[x].r>>1;
	long long ans=0;
	if(l<=mid) ans+=quesum(x<<1,l,r);
	if(r>mid) ans+=quesum(x<<1|1,l,r);
	return ans;
}
inline void change(int pos,long long k)
{
	update(1,t[pos].id,k);//就是这里,我之前写成了update(1,pos,k);
}
long long qmax(int u,int v)
{
	long long ans=-99999999;
	while(t[u].top!=t[v].top)
	{
		if(t[t[u].top].dep<t[t[v].top].dep) std::swap(u,v);
		ans=std::max(ans,quemx(1,t[t[u].top].id,t[u].id));
		u=t[t[u].top].fa;
	}
	if(t[u].id>t[v].id) std::swap(u,v);
	ans=std::max(ans,quemx(1,t[u].id,t[v].id));
	return ans;
}
long long qsum(int u,int v)
{
	long long ans=0;
	while(t[u].top!=t[v].top)
	{
		if(t[t[u].top].dep<t[t[v].top].dep) std::swap(u,v);
		ans+=quesum(1,t[t[u].top].id,t[u].id);
		u=t[t[u].top].fa;
	}
	if(t[u].id>t[v].id) std::swap(u,v);
	ans+=quesum(1,t[u].id,t[v].id);
	return ans;
}
int main()
{
	//freopen("test.in","r",stdin);
	scanf("%d",&n);
	for(int i=1,u,v;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		add(u,v);
	}
	for(int i=1;i<=n;i++) scanf("%lld",&t[i].w);
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	scanf("%d",&q);
	while(q--)
	{
		char opt[20]={0};
		int x,y;
		scanf("%s%d%d",opt,&x,&y);
		if(opt[1]=='H') change(x,(long long)y);
		else if(opt[1]=='M') printf("%lld\n",qmax(x,y));
		else printf("%lld\n",qsum(x,y));
	}
}
洛谷 P2590 BZOJ 1036 [ZJOI2008]树的统计的更多相关文章
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
		BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ... 
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
		1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ... 
- BZOJ 1036: [ZJOI2008]树的统计Count
		1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 14354 Solved: 5802 [Subm ... 
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
		1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ... 
- Bzoj 1036: [ZJOI2008]树的统计Count  树链剖分,LCT
		1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ... 
- 数据结构(LCT动态树):BZOJ 1036: [ZJOI2008]树的统计Count
		1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 12266 Solved: 4945[Submit ... 
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
		树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ... 
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
		1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ... 
- bzoj 1036: [ZJOI2008]树的统计Count (树链剖分+线段树 点权)
		1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 21194 Solved: 8589[Submit ... 
随机推荐
- 【ABAP系列】SAP ABAP 从FTP服务器读取文件到本地
			公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 从FTP服务器 ... 
- 【Python】利用豆瓣短评数据生成词云
			在之前的文章中,我们获得了豆瓣爬取的短评内容,汇总到了一个文件中,但是,没有被利用起来的数据是没有意义的. 前文提到,有一篇微信推文的关于词云制作的一个实践记录,准备照此试验一下. 思路分析 读文件 ... 
- linux系统中不小心执行了rm -rf ./* 怎么办?解决:文件系统的备份与恢复
			XFS提供了 xfsdump 和 xfsrestore 工具协助备份XFS文件系统中的数据.xfsdump 按inode顺序备份一个XFS文件系统.centos7选择xfs格式作为默认文件系统,而且不 ... 
- java版微信支付/查询/撤销
			最近公司接入微信刷卡支付,网上根本没见到很直接的教程(可能眼拙),一直摸滚打爬,加班加点才走通,忍不了必须写一写 微信 刷卡支付/查询/撤销... 必须要有公众号然后去申请,申请自己去看文档,这里主要 ... 
- 右键windows terminal here无法进入当前目录
			很久没写水笔了,简单记一水 使用windows terminal的基本上都自己改过注册表,添加到右键windows terminal here吧,用着很方便,哪里不会点哪里. 我起初删除掉starti ... 
- sprintf()函数可能发生的错误
			接收到如下数据: GET http://app.tdvpn.com/heartbeat?mac=898607B81017AT+CIPSTATUS? &status=/ HTTP/1.1 Hos ... 
- 消息中间件 JMS入门
			1. JMS入门 1.1消息中间件 什么是消息中间件 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排队模型,它可以在分布式环 ... 
- 图论 test solution
			图论 test solution T1:潜伏 题目背景 小悠回家之后,跟着母亲看了很多抗日神剧,其中不乏一些谍战片. 题目描述 解放前夕,北平城内潜伏着若干名地下党员,他们居住在城市的不同位置.现在身 ... 
- HNUSTOJ-1636 心电图
			1636: 心电图 时间限制: 1 Sec 内存限制: 128 MB提交: 583 解决: 231[提交][状态][讨论版] 题目描述 众所周知,ACM/ICPC实验室聚集了一堆学霸Orz 有学霸 ... 
- linux的mv、cp 命令
			用mv命令1.作用mv命令来为文件或目录改名或将文件由一个目录移入另一个目录中.该命令等同于DOS系统下的ren和move命令的组合.它的使用权限是所有用户.2.格式mv [options] 源文件或 ... 
