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 ...
随机推荐
- 【bzoj3671】[Noi2014]随机数生成器 贪心
题目描述 输入 第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子.第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N×M 的排列来填入她 N ...
- BZOJ 4589 Hard Nim ——FWT
[题目分析] 位运算下的卷积问题. FWT直接做. 但还是不太民白,发明者要承担泽任的. [代码] #include <cstdio> #include <cstring> # ...
- [luoguP2518][HAOI2010]计数(数位DP)
传送门 重新学习数位DP.. 有一个思路,枚举全排列,然后看看比当前数小的有多少个 当然肯定是不行的啦 但是我们可以用排列组合的知识求出全排列的个数 考虑数位dp 套用数位dp的方法,枚举每一位,然后 ...
- 【CCF】行车路线 改编Dijkstra
[AC] #include<iostream> #include<cstdio> #include<string> #include<cstring> ...
- farm
farm 时间限制:C/C++ 4秒,其他语言8秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 White Rabbit has ...
- 作诗(bzoj 2821)
Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗 之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次 ...
- 洛谷 [P2216] 理想的正方形
二维单调队列 先横向跑一边单调队列,记录下每一行长度为n的区间的最值 在纵向跑一边单调队列,得出结果 注意,mi要初始化为一个足够大的数 #include <iostream> #incl ...
- 并发编程辅助工具-java.util.concurrent
1. CountDownLatch 类似于计数器的功能,主要用于控制某个任务的执行先后顺序,可以控制某个任务在其他任务(可能是多线程的)执行完 之后,才会去执行. public static void ...
- elasticsearch入门使用(二) Mapping + field type字段类型
Elasticsearch Reference [6.2] » Mapping 参考官方英文文档 https://www.elastic.co/guide/en/elasticsearch/refer ...
- mysql 5.7版本目录无data文件夹的解决办法
安装mysql 5.7+版本时,若发现因根目录下,缺少data文件夹的情况, ***请不要去拷贝其他版本的data文件夹!*** 因为此操作会出现很多潜在问题:比如我遇到的执行show variabl ...