BZOJ5379: Tree
Description
JudgeOnline/upload/201806/1.pdf
题解Here!
#include<iostream>
#include<algorithm>
#include<cstdio>
#define LSON rt<<1
#define RSON rt<<1|1
#define DATA(x) b[x].data
#define SIGN(x) b[x].c
#define LSIDE(x) b[x].l
#define RSIDE(x) b[x].r
#define WIDTH(x) (RSIDE(x)-LSIDE(x)+1)
#define MAXN 300010
using namespace std;
int n,m,c=1,d=1,root=1;
int val[MAXN],head[MAXN],deep[MAXN],son[MAXN],size[MAXN],fa[MAXN],id[MAXN],pos[MAXN],top[MAXN];
struct Tree{
int next,to;
}a[MAXN<<1];
struct Segment_Tree{
long long data,c;
int l,r;
}b[MAXN<<2];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline void add(int x,int y){
a[c].to=y;a[c].next=head[x];head[x]=c++;
a[c].to=x;a[c].next=head[y];head[y]=c++;
}
void dfs1(int rt){
son[rt]=0;size[rt]=1;
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(!deep[will]){
deep[will]=deep[rt]+1;
fa[will]=rt;
dfs1(will);
size[rt]+=size[will];
if(size[son[rt]]<size[will])son[rt]=will;
}
}
}
void dfs2(int rt,int f){
id[rt]=d++;pos[id[rt]]=rt;top[rt]=f;
if(son[rt])dfs2(son[rt],f);
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(will!=fa[rt]&&will!=son[rt])dfs2(will,will);
}
}
inline void pushup(int rt){
DATA(rt)=DATA(LSON)+DATA(RSON);
}
inline void pushdown(int rt){
if(!SIGN(rt)||LSIDE(rt)==RSIDE(rt))return;
SIGN(LSON)+=SIGN(rt);
DATA(LSON)+=SIGN(rt)*WIDTH(LSON);
SIGN(RSON)+=SIGN(rt);
DATA(RSON)+=SIGN(rt)*WIDTH(RSON);
SIGN(rt)=0;
}
void buildtree(int l,int r,int rt){
LSIDE(rt)=l;RSIDE(rt)=r;SIGN(rt)=0;
if(l==r){
DATA(rt)=val[pos[l]];
return;
}
int mid=l+r>>1;
buildtree(l,mid,LSON);
buildtree(mid+1,r,RSON);
pushup(rt);
}
void update(int l,int r,long long c,int rt){
if(l<=LSIDE(rt)&&RSIDE(rt)<=r){
SIGN(rt)+=c;
DATA(rt)+=c*WIDTH(rt);
return;
}
pushdown(rt);
int mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)update(l,r,c,LSON);
if(mid<r)update(l,r,c,RSON);
pushup(rt);
}
long long query(int l,int r,int rt){
long long ans=0;
if(l<=LSIDE(rt)&&RSIDE(rt)<=r)return DATA(rt);
pushdown(rt);
int mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)ans+=query(l,r,LSON);
if(mid<r)ans+=query(l,r,RSON);
return ans;
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
return x;
}
int check(int x){
if(x==root)return -1;
if(id[x]<=id[root]&&id[root]<=id[x]+size[x]-1){
int y=root;
while(deep[y]>deep[x]){
if(fa[top[y]]==x)return top[y];
y=fa[top[y]];
}
return son[x];
}
return 0;
}
void update_subtree(int x,int k){
int y=check(x);
if(y==-1)update(1,n,k,1);
else if(y==0)update(id[x],id[x]+size[x]-1,k,1);
else{
update(1,n,k,1);
update(id[y],id[y]+size[y]-1,-k,1);
}
}
void query_subtree(int x){
long long s;
int y=check(x);
if(y==-1)s=query(1,n,1);
else if(y==0)s=query(id[x],id[x]+size[x]-1,1);
else s=query(1,n,1)-query(id[y],id[y]+size[y]-1,1);
printf("%lld\n",s);
}
void work(){
int f,x,y,k;
while(m--){
f=read();x=read();
if(f==1)root=x;
else if(f==2){
y=read();k=read();
int lca=LCA(x,y),lca1=LCA(x,root),lca2=LCA(y,root);
if(deep[lca1]>deep[lca])lca=lca1;
if(deep[lca2]>deep[lca])lca=lca2;
update_subtree(lca,k);
}
else query_subtree(x);
}
}
void init(){
int x,y;
n=read();m=read();
for(int i=1;i<=n;i++)val[i]=read();
for(int i=1;i<n;i++){
x=read();y=read();
add(x,y);
}
deep[1]=1;
dfs1(1);
dfs2(1,1);
buildtree(1,n,1);
}
int main(){
init();
work();
return 0;
}
BZOJ5379: Tree的更多相关文章
- [bzoj5379]Tree_dfs序_线段树_倍增lca
Tree bzoj-5379 题目大意:给定一棵$n$节点的树.支持:换根.把节点$u$和$v$的$lca$的子树加.询问$u$的子树和. 注释:$1\le n,q\le 3\times 10^5$. ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- SAP CRM 树视图(TREE VIEW)
树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...
- 无限分级和tree结构数据增删改【提供Demo下载】
无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...
- 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
随机推荐
- Python 频繁读取Mysql相关问题
1.需要频繁select大量数据,时间长.消耗内存大,如何解决mysql性能问题? 如果对返回的结果数量没有要求,可以控制返回的数量: cursor.fetchmany(size=1000) 这样是只 ...
- [HNOI2002]彩票 (搜索+剪枝)
题目描述 某地发行一套彩票.彩票上写有1到M这M个自然数.彩民可以在这M个数中任意选取N个不同的数打圈.每个彩民只能买一张彩票,不同的彩民的彩票上的选择不同. 每次抽奖将抽出两个自然数X和Y.如果某人 ...
- leetcode 319 灯泡问题
例子:1-9 1的因子1 2 1,2 3 1,,3 4 1,2,4 5 1,5 6 1,2,3,6 7 1,7 8 ...
- java面试题之stop()和suspend()方法为何不不推荐使⽤?
stop方法:他是不安全的,他会停止所有运行中的线程: suspend方法:容易发生死锁,虽然调用suspend方法目标线程会停下来,但是仍然持有之前的锁,其他线程都不能访问锁定的资源,就会造成死锁, ...
- bzoj 2017 [Usaco2009 Nov]硬币游戏 动态规划
[Usaco2009 Nov]硬币游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 431 Solved: 240[Submit][Status] ...
- bzoj2748 [HAOI2012]音量调节 背包
Description 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量.在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改 ...
- 转:WOM 编码与一次写入型存储器的重复使用
转自:WOM 编码与一次写入型存储器的重复使用 (很有趣的算法设计)——来自 Matrix67: The Aha Moments 大神 计算机历史上,很多存储器的写入操作都是一次性的. Wikiped ...
- idea打包SpringBoot项目打包成jar包和war
- 打包成jar包 1. <groupId>com.squpt.springboot</groupId> <artifactId>springbootdemo< ...
- Codevs 1299 切水果 水一发
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 简单的说,一共N个水果排成一排,切M次,每次切[L,R]区间的所有水果(可能有的 ...
- Scrapy学习-7-数据存储至数据库
使用MySQL数据库存储 安装mysql模块包 pip install mysqlclient 相关库文件 sudo apt-get install libmysqlclient-devel sudo ...