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传入参数
项目中时常会使用php编写脚本,进行一些统计与批量更新的需求需要进行操作其中使用的方式主要是getopt函数,写法如下 <?php $opt = getopt('m:n:'); $value_m ...
- 【笔记】LR11中关联设置
LR中关联建议都手动进行,自动不好用,也容易出错. 在LR中我们什么要做关联:1.关联解决的是动态数据的参数化.2.关联的数据一定是服务器响应的数据.3.服务器响应过来的数据在后面的服务还要使用. 手 ...
- laravel-admin列表排序在使用了$grid->model()->latest()后$grid其它加上sortable()可排序的列在排序时不起作用
laravel-admin这个基于laravel的后台框架,简单易用,$grid的默认排序是主键升序的排列方式,但在使用了`$grid->model()->latest();`自定义默认排 ...
- jeecms使用小结
前言: 使用jeecmsV9已经有一段时间,现在PC端的二次开发基本进入尾声,手机端的开发即将开始 ,由于项目时间比较紧,开发时不是每个人都会使用它自带的标签,所以在PC端开发的时候浪费了大量时间,为 ...
- 数据库操作之Spring JDBCTemplate(postgresql)
本文总结了两种使用JDBCTemplate进行数据库CRUD操作的例子,我用的是pg,废话不说,直接开始吧. 先贴一张目录结果图吧: 上图中最主要的是配置文件和所需的各种jar包. 一.通过属性文件的 ...
- Django 创建web项目之HelloWorld
Django.Flask.Tornado并称为python WEB三大框架.Diango是一个开源的web应用框架,具有开发速度快的特点.同时因为过度封装,具有性能低的特点. 创建Django项目,启 ...
- django中的聚合索引
Django(元信息)元类建索引 ORM查询(sql优化)优化 自定义聚合函数 Django的元类建索引————索引:索引的一个主要目的就是加快检索表中数据,索引是经过某种算法优化过的,因而查找次数要 ...
- vue-li+webpack+iview构建项目步骤
首先安装各类插件 npm install vue-cli -g vue init webpack demo npm install iview --save npm install less styl ...
- PHP--反射的方法
反射,直观理解就是根据到达地找到出发地和来源.比如,一个光秃秃的对象,我们可以仅仅通过这个对象就能知道它所属的类.拥有哪些方法. 反射是指�php运行状态中,扩展分析PHP程序,导出或提出关于类.方法 ...
- Javascript实现信息滚动效果的方法
<html><head><meta http-equiv="Content-Type" content="text/html; charse ...