HZOJ Tree
看到换根果断lct啊,然而其实我板子还没有打熟,还不会维护子树信息,于是就挂掉了……
然而正解并不是lct。
其实好像很久很久以前将lca的时候好像讲到过一道换根的题,当时没有听懂。
直接说正解吧:
把dfs序搞出来用线段树维护。
用一个变量记录当前根节点,操作一直接改就行了。
然后是操作三:
分情况讨论,设当前根节点为root,询问的点为a。
如果root不在a的子树内,那么root不会影响a的子树,仍然输出1为根时的子树和就行了。
如果在子树内,

如图,如果要查询1的子树和,那么找到1与root这条链上靠近1的点,整体的和减去这个点的子树和就是了。(感性理解一下。)
那么这个点怎么求呢?只需要对于每个点把与他直接相连的儿子的dfs序塞到一个vector里,upper_bound然后-1就可以了。
操作二:
首先求出以1为根是a,b两点的lca。
与操作三类似,如果root不在lca的子树内,那么root不会影响lca,直接加就行。
如果在子树内,那么找a,b与root的lca中深度较大的那个。
之后就和操作三一样了。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define LL long long
#define re register
#define co const
#define rec re co
#define inline __attribute((always_inline))
const int LLL=<<|;
char buffer[LLL],*S,*TT;
#define getchar() ((S==TT&&(TT=(S=buffer)+fread(buffer,1,LLL,stdin),S==TT))?EOF:*S++)
using namespace std;
struct edge
{
int u,v,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define n(x) ed[x].nxt
}ed[];
int first[],num_e;
#define f(x) first[x]
int n,q,w[];
bool pd2=,pd3=;
vector<int> inc[];
LL fa[][],dep[];
int dfn[],id[],cnt,L[],R[];LL res;
int siz[],son[],top[];
void dfs1(int x)
{
siz[x]=;
for(int i=f(x);i;i=n(i))
if(v(i)!=fa[x][])
{
fa[v(i)][]=x;dep[v(i)]=dep[x]+;
dfs1(v(i));siz[x]+=siz[v(i)];
if(siz[v(i)]>siz[son[x]])son[x]=v(i);
}
}
void dfs2(int x,int t)
{
top[x]=t;dfn[x]=++cnt;id[cnt]=x;L[x]=cnt;
if(son[x])dfs2(son[x],t),inc[x].push_back(dfn[son[x]]);
for(int i=f(x);i;i=n(i))
if(v(i)!=fa[x][]&&v(i)!=son[x])
dfs2(v(i),v(i)),inc[x].push_back(dfn[v(i)]);
R[x]=cnt;
}
inline int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])swap(x,y);
y=fa[top[y]][];
}
if(dep[x]>dep[y])swap(x,y);
return x;
}
struct xjs_Tree
{
struct tree
{
int l,r;LL sum,la;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define la(x) tr[x].la
#define sum(x) tr[x].sum
#define ls(x) ((x)<<1)
#define rs(x) (ls(x)+1)
}tr[];
void build(rec int x,rec int l,rec int r)
{
l(x)=l,r(x)=r,la(x)=;
if(l==r){sum(x)=w[id[l]];return;}
int mid=(l+r)>>;
build(ls(x),l,mid);
build(rs(x),mid+,r);
sum(x)=sum(ls(x))+sum(rs(x));
}
inline void down(rec int x)
{
if(l(x)==r(x))return;
if(!la(x))return;
sum(ls(x))+=(r(ls(x))-l(ls(x))+)*la(x);
sum(rs(x))+=(r(rs(x))-l(rs(x))+)*la(x);
la(ls(x))+=la(x);la(rs(x))+=la(x);la(x)=;
}
void add(rec int x,rec int l,rec int r,rec LL y)
{
if(l>r)return;
down(x);
if(l(x)>=l&&r(x)<=r)
{
sum(x)+=(r(x)-l(x)+)*y;
la(x)+=y;return;
}
int mid=(l(x)+r(x))>>;
if(l<=mid)add(ls(x),l,r,y);
if(r> mid)add(rs(x),l,r,y);
sum(x)=sum(ls(x))+sum(rs(x));
}
LL ask(rec int x,rec int l,rec int r)
{
if(l>r)return ;
down(x);
if(l(x)>=l&&r(x)<=r)return sum(x);
int mid=(l(x)+r(x))>>;LL ans=;
if(l<=mid)ans+=ask(ls(x),l,r);
if(r> mid)ans+=ask(rs(x),l,r);
return ans;
}
}T;
inline int read();
inline void add(rec int u,rec int v);
signed main()
{
// freopen("S1_1.in","r",stdin);
// freopen("in.txt","r",stdin);
// freopen("1.out","w",stdout); n=read(),q=read();int tu,tv;
for(re int i=;i<=n;i++)w[i]=read();
for(re int i=;i<n;i++)tu=read(),tv=read(),add(tu,tv),add(tv,tu);
re int root=;
dep[]=;dfs1(),dfs2(,);T.build(,,n);
re int opt,a,b,c;
for(re int i=;i<=q;i++)
{
opt=read();
if(opt==)a=read(),root=a;
if(opt==)
{
a=read(),b=read(),c=read();
int lca=LCA(a,b);
if(lca==root)T.add(,,n,c);
else if(dfn[root]<L[lca]||dfn[root]>R[lca])T.add(,L[lca],R[lca],c);
else
{
int t1=LCA(a,root),t2=LCA(b,root);
if(dep[t1]>dep[t2])lca=t1;
else lca=t2;
if(lca==root)T.add(,,n,c);
else if(dfn[root]<L[lca]||dfn[root]>R[lca])T.add(,L[lca],R[lca],c);
else
{
int te=upper_bound(inc[lca].begin(),inc[lca].end(),dfn[root])-inc[lca].begin()-;
lca=inc[lca][te];lca=id[lca];
T.add(,,L[lca]-,c),T.add(,R[lca]+,n,c);
}
}
}
if(opt==)
{
a=read();
if(a==root)printf("%lld\n",T.ask(,,n));
else if(dfn[root]<L[a]||dfn[root]>R[a])printf("%lld\n",T.ask(,L[a],R[a]));
else
{
int te=upper_bound(inc[a].begin(),inc[a].end(),dfn[root])-inc[a].begin()-;
te=inc[a][te];te=id[te];
printf("%lld\n",T.ask(,,L[te]-)+T.ask(,R[te]+,n));
}
}
}
return ;
}
inline int read()
{
int s=,f=;char a=getchar();
while(a<''||a>''){if(a=='-')f=-;a=getchar();}
while(a>=''&&a<=''){s=s*+a-'';a=getchar();}
return s*f;
}
inline void add(rec int u,rec int v)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
n(num_e)=f(u);
f(u)=num_e;
}
HZOJ Tree的更多相关文章
- [数据结构]——二叉树(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 ...
- Leetcode 笔记 101 - Symmetric Tree
题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...
随机推荐
- php mkdir 777失败
参考网址:https://www.cnblogs.com/52php/p/5660079.html 在linux系统中在创建文件/文件夹时有一个默认权限,此权限受 umask 设置影响,在/etc/b ...
- web服务器--nginx简介
nginx 介绍Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务.Nginx是一款轻量级的Web 服务器/反向代理服务器及电 ...
- didFailWithError: Error Domain=kCLErrorDomain Code=0 “The operation couldn’t be completed. (kCLError
This error also occurs if you have Scheme/Edit Scheme/Options/Allow Location Simulation checked but ...
- C# EventWaitHandle用法
waithander就是用来阻塞当前线程的,然后通过set()方法放开 namespace waithandler { class Program { //static EventWaitHandle ...
- js点击复制文本
// 动态创建 input 元素 var aux = document.createElement("input"); // 获得需要复制的内容 aux.setAttribute( ...
- 数据库---JDBC的解析
一.JDBC是什么? JDBC:Java Database Connectivity(Java数据库连接池).指定了统一的访问各种关系型数据库的标准接口-----桥梁作用. 功能:[与数据库建立连接 ...
- Centos7搭建Django出现的问题(Centos7+Django1.11.1+Nginx+uwsgi)
出现的问题: 1.pip未安装:http://www.cnblogs.com/fnng/p/3737964.html 2.安装uwsgi失败,因为未安装python-devel yum search ...
- ios开发ARC,IBOutlets之strong与weak
今天在写程序的时候,用IBOutlets连了一个自定义的控件,出现了问题,后面访问的时候,控件里有些subviews没有初始化好,取到的时候为nil, 程序里用了ARC, IBOutlets一连接上, ...
- Sublime text2 常用插件
很早就安装了这款软件,因为听说很NB.但是一直都是习惯用vim, 所以一直没有去学习它, 现在用用感觉确实很不错,所以找了些插件, 参考网址: http://www.hphq.net/Marketin ...
- jquery.dataTables的探索之路-服务端分页配置
最近闲来无事想研究下数据表格,因为之前接触过layui和bootstrap的数据表格,本着能学多少学多少的学习态度,学习下dataTables的服务端分页配置.特与同学们一块分享下从中遇到的问题和解决 ...