【HAOI2015】树上操作(树链剖分模板)_WWWengine的博客-程序员秘密

技术标签: 数据结构  

原题见洛谷。

既然是模板,没什么可分析的,只是有几个小地方:

1,两种修改操作可以合并为一个,只需写区间修改,然后对于点修改,把区间两端都设为点的DFS序即可。

2,询问时,可以不用改模板,直接当作u=1,另一个v输入。

3,没事就pushup一下,至少不会错。

4,要用long long。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=100005;
int lc[MAXN*2],rc[MAXN*2];
int last[MAXN],fa[MAXN],size[MAXN],dep[MAXN],top_node[MAXN],big_son[MAXN],dfs_pos[MAXN],a[MAXN],b[MAXN];
int N,M,np=0,np2=0,rt=0,dfs_clock=0;
LL sum[MAXN*2],lazy[MAXN*2];
struct edge{int to,pre;}E[MAXN*2];

char c;int flag;
void scan(int &x)
{
	flag=1;
	for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
	if(c=='-') flag=-1,c=getchar();
	for(x=0;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
	x*=flag;
}

char num[50];int ct;
void print(LL x)
{
	ct=0;
	if(x<0) putchar('-'),x=-x;
	if(!x) num[ct++]='0';
	while(x) num[ct++]=x%10+'0',x/=10;
	while(ct--) putchar(num[ct]);
	putchar('\n');
}
//------------------------------------
void addedge(int u,int v)
{
	E[++np2]=(edge){v,last[u]};
	last[u]=np2;
}

void DFS1(int i,int f,int d)
{
	dep[i]=d; fa[i]=f; size[i]=1;
	for(int p=last[i];p;p=E[p].pre)
	{
		int j=E[p].to;
		if(j==f) continue;
		DFS1(j,i,d+1); size[i]+=size[j];
		if(size[j]>size[big_son[i]]) big_son[i]=j;
	}
}

void DFS2(int i,int top)
{
	dfs_pos[i]=++dfs_clock;
	top_node[i]=top; b[dfs_clock]=a[i];
	if(!big_son[i]) return;
	DFS2(big_son[i],top);
	for(int p=last[i];p;p=E[p].pre)
	{
		int j=E[p].to;
		if(j==fa[i]||j==big_son[i]) continue;
		DFS2(j,j);
	}
}
//-------------------------------------
void pushup(int now) {sum[now]=sum[lc[now]]+sum[rc[now]];}

void build(int &now,int L,int R)
{
	if(!now) now=++np;
	if(L==R)
	{
		sum[now]=(LL)b[L];
		return;
	}
	int mid=(L+R)/2;
	build(lc[now],L,mid);
	build(rc[now],mid+1,R);
	pushup(now);
}

void f(int now,int L,int R,LL d)
{
	lazy[now]+=d;
	sum[now]+=(LL)(R-L+1)*d;
}

void pushdown(int now,int L,int R)
{
	if(!lazy[now]) return;
	int mid=(L+R)/2;
	f(lc[now],L,mid,lazy[now]);
	f(rc[now],mid+1,R,lazy[now]);
	lazy[now]=0;
}

void update(int now,int L,int R,int i,int j,LL d)
{
	if(i<=L&&R<=j)
	{
		lazy[now]+=d;
		sum[now]+=(LL)(R-L+1)*d;
		return;
	}
	pushdown(now,L,R);
	int mid=(L+R)/2;
	if(i<=mid) update(lc[now],L,mid,i,j,d);
	if(mid<j) update(rc[now],mid+1,R,i,j,d);
	pushup(now);
}

LL ques(int now,int L,int R,int i,int j)
{
	if(i<=L&&R<=j) return sum[now];
	pushdown(now,L,R);
	int mid=(L+R)/2; LL ans=0;
	if(i<=mid) ans+=ques(lc[now],L,mid,i,j);
	if(mid<j) ans+=ques(rc[now],mid+1,R,i,j);
 	pushup(now); return ans;
}

LL ques_range(int u,int v)
{
	LL ans=0;
	while(top_node[u]!=top_node[v])
	{
		if(dep[top_node[u]]<dep[top_node[v]]) swap(u,v);
		ans+=ques(rt,1,N,dfs_pos[top_node[u]],dfs_pos[u]);
		u=fa[top_node[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	return ans+ques(rt,1,N,dfs_pos[u],dfs_pos[v]);
}

int main()
{
	int i,u,v,w,op;
	scan(N);scan(M);
	for(i=1;i<=N;i++) scan(a[i]);
	for(i=1;i<N;i++)
	{
		scan(u);scan(v);
		addedge(u,v);
		addedge(v,u);
	}
	DFS1(1,0,1); DFS2(1,1); build(rt,1,N);
	while(M--)
	{
		scan(op);
		if(op==1)
		{
			scan(u);scan(w);
			update(rt,1,N,dfs_pos[u],dfs_pos[u],(LL)w);
		}
		else if(op==2)
		{
			scan(u);scan(w);
			update(rt,1,N,dfs_pos[u],dfs_pos[u]+size[u]-1,(LL)w);
		}
		else
		{
			scan(u);
			print(ques_range(1,u));
		}
	}
	return 0;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/WWWengine/article/details/81661926

智能推荐

数据结构----队列,双向队列(Deque),循环队列_咸鱼妹WWW的博客-程序员秘密

1.队列的基本知识 队列的基本特性就是先进先出(FIFO),也就是第一个进去的元素第一个出来。即队列就是一个只允许在一端进行插入,在另一端进行删除操作的线性表。Queue接口与List、Set同一级别,都是继承了Collection接口。2.队列按照实现方式也分为两种:①单向队列(Queue):只能在一段插入数据,另一端删除数据。②双向队列(Deque):每一段都可以进行插入数据和删除数据的操作。3.双向队列(LinkedList实现了Deque接 口) 双向队列是一个线...

Window10环境下的LaTex全套详细安装教程(TeXLive2021+WinEdt+sumatraPDF)_latex windows_橙子和鱼我最爱的博客-程序员秘密

安装前的小提醒:LaTex安装好后估计有7个G左右,主要是TexLive比较大,所以安装前要一定要确保有足够的空间存放;根据经验,比较大的文件安装起来,那时间得老久老久了,就算你的硬盘是SSD,那也快不了多少,少说也得将近1小时…安装目录的文件名一定要是英文的,也不要有-、之类的符号,不然前面的一个小时,差不多是都废了TeXLive2021安装链接TeX Live 的当前版本是 2021,你可以从官方站点下载它们的安装包。点击下列链接,将会「自动选择」距离你最近

webpack4.0入门学习总结(一)_3Alan的博客-程序员秘密

这一篇文章主要简单介绍了webpack是什么以及webpack的一些简单配置,你只要跟着我敲完这些代码后一定会对webpack有一个基本的了解的。????webpack是一个模块打包器本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。上面引用了web

Spring Cloud:Eureka 2.X 停止开发,但注册中心还有更多选择:Consul 使用详解(13)_贾诩是也的博客-程序员秘密

在上个月我们知道 Eureka 2.X 遇到困难停止开发了,但其实对国内的用户影响甚小,一方面国内大都使用的是 Eureka 1.X 系列,另一方面 Spring Cloud 支持很多服务发现的软件,Eureka 只是其中之一,下面是 Spring Cloud 支持的服务发现软件以及特性对比:Feature euerka Consul zookeeper etcd ...

23种设计模式-解释器模式_六块腹肌的程序猿的博客-程序员秘密

四则运算问题:通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求1)先输入表达式的形式,比如 a+b+c-d+e, 要求表达式的字母不能重复2)在分别输入 a ,b, c, d, e 的值3)最后求出结果:如图传统解决方案:1)编写一个方法,接收表达式的形式,然后根据用户输入的数值进行解析,得到结果2)问题分析:如果加入新的运算符,比如 * / ( 等等,不利于扩展,另外让一个方法来解析会造成程序结构混乱, 不够清晰.3)解决方案:可以考虑使用解释器模式, 即: 表达式

linux内核如何再优化,Linux内核网络性能优化_康上明学的博客-程序员秘密

1. 前言本文将简单介绍Linux内核网络协议栈的流程,并总结常见的网络优化技术,使用尽量多的图片帮助理解原理,感谢阅读。2. Linux网络协议栈数据包在内核中使用sk_buff结构体来传递。网络套接字是用sock结构体来定义的,该结构体在各网络协议结构体的开头部分存放,例如tcp_sock。网络协议使用proto结构体挂载到网络套接字结构体上,例如tcp_prot、udp_prot等,该结构体...

随便推点

transition过度效果 + transform旋转360度_weixin_30293079的博客-程序员秘密

css样式:.animate{ width:65px; height:40px; background:#92B901; color:#ffffff; position:absolute; font-weight:bold; font:12px '微软雅黑', Verdana, Arial, Helvetica, sans-serif; ...

正则表达式的替换技巧_正则替换_庚庚911的博客-程序员秘密

正则表达式应用——替换指定内容到行尾 正则表达式应用——数字替换 正则表达式应用——删除每一行行尾的指定字符 正则表达式应用——替换带有半角括号的多行 正则表达式应用——删除空行 正则表达式应用——实例应用1.正则表达式应用——替换指定内容到行尾原始文本如下面两行abc aaaaa123 abc 444希望每次遇到“abc”,则替换“abc”以及其后到行尾的内容为“ab...

localstorage与storage事件监听_localstorage storage事件_Yetian_2000的博客-程序员秘密

引用《h5移动web开发指南》上的话:“当同源页面的某个页面修改了localStorage,其余的同源页面只要注册了storage事件,就会触发”所以,localStorage storage的例子运行需要如下条件:1. 同一浏览器打开了两个同源页面(同源页面:即同一个电脑里面的同一个文件夹,里面的不同的html页面)2.其中一个网页修改了localStorage(A页面修改了localstorge)3. 另一网页注册了storage事件(B页面能监听到变化)参考代码地址:暂无...

解决拦截器中获取了requestbody之后在controller中获取不到requestbody的问题_weixin_30558305的博客-程序员秘密

@requestbody使用的是流获取获取输出的参数。而在拦截器中获取的方式也是流在spring的框架里面获取参数只能调用一次于是自定义了一个过滤器将流先在过滤器里面获取到,然后再写进去就行了,这样的话就可以一直获取了import java.io.IOException;import javax.servlet.FilterChain;import javax.servle...

英国脱欧 欧盟授权代表_英国脱欧可能影响您的虚拟主机的3种方式_culin0274的博客-程序员秘密

英国脱欧 欧盟授权代表As the likelihood of a no-deal Brexit increases, businesses throughout the UK will be taking stock of what they need to do come October 31. One area that many businesses might have overloo...

相关性系数和显著性水平_相关系数和显著性水平的关系_yangguangjll的博客-程序员秘密

相关性系数和显著性水平在统计学中,皮尔逊相关系数( Pearson correlation coefficient),又称皮尔逊积矩相关系数(Pearson product-moment correlation coefficient,简称 PPMCC或PCCs)&lt;很多英文文献中的叫法&gt;,是用于度量两个变量X和Y之间的相关(线性相关),其值介于-1与1之间。P值,也就是Sig值或显著性值。如果P值小于0.01即说明某件事情的发生至少有99%的把握,如果P值小于0.05(并且大于0.01)则说

推荐文章

热门文章

相关标签