[CodeVS4633][Mz]树链剖分练习
思路:
轻重链剖分+线段树。
#include<cstdio>
#include<vector>
#include<cstring>
const int N=;
std::vector<int> e[N];
inline void add_edge(const int u,const int v) {
e[u].push_back(v);
e[v].push_back(u);
}
int par[N]={,},dep[N]={},size[N]={};
void dfs1(const int x) {
size[x]=;
for(unsigned int i=;i<e[x].size();i++) {
if(e[x][i]==par[x]) continue;
par[e[x][i]]=x,dep[e[x][i]]=dep[x]+;
dfs1(e[x][i]);
size[x]+=size[e[x][i]];
}
}
int top[N]={},dfn[N],sz=;
void dfs2(const int x) {
if(!top[x]) top[x]=x;
dfn[x]=++sz;
if(e[x].size()==&&x!=) return;
int v=;
for(unsigned int i=;i<e[x].size();i++) {
if(e[x][i]==par[x]) continue;
if(size[e[x][i]]>size[v]) v=e[x][i];
}
top[v]=top[x];
dfs2(v);
for(unsigned int i=;i<e[x].size();i++) {
if(e[x][i]==par[x]||e[x][i]==v) continue;
dfs2(e[x][i]);
}
}
class SegmentTree {
#define _left <<1
#define _right <<1|1
private:
int val[N<<],tag[N<<];
int len(const int l,const int r) {
return r-l+;
}
void push_down(const int p,const int b,const int e) {
if(!tag[p]) return;
int mid=(b+e)>>;
tag[p _left]+=tag[p];
tag[p _right]+=tag[p];
val[p _left]+=tag[p]*len(b,mid);
val[p _right]+=tag[p]*len(mid+,e);
tag[p]=;
}
void push_up(const int p) {
val[p]=val[p _left]+val[p _right];
}
public:
SegmentTree() {
memset(val,,sizeof val);
memset(tag,,sizeof tag);
}
void modify(const int p,const int b,const int e,const int l,const int r) {
if((b==l)&&(e==r)) {
val[p]+=len(b,e);
tag[p]++;
return;
}
push_down(p,b,e);
int mid=(b+e)>>;
if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r));
if(r>mid) modify(p _right,mid+,e,std::max(mid+,l),r);
push_up(p);
}
int query(const int p,const int b,const int e,const int l,const int r) {
if((b==l)&&(e==r)) return val[p];
push_down(p,b,e);
int mid=(b+e)>>,ans=;
if(l<=mid) ans+=query(p _left,b,mid,l,std::min(mid,r));
if(r>mid) ans+=query(p _right,mid+,e,std::max(mid+,l),r);
return ans;
}
};
SegmentTree t;
inline void swap(int &x,int &y) {
int t;
t=x;
x=y;
y=t;
}
int n;
void modify(int x,int y) {
for(;top[x]!=top[y];x=par[top[x]]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
t.modify(,,n,dfn[top[x]],dfn[x]);
}
if(dep[x]<dep[y]) swap(x,y);
t.modify(,,n,dfn[y],dfn[x]);
}
int query(int x,int y) {
int ans=;
for(;top[x]!=top[y];x=par[top[x]]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=t.query(,,n,dfn[top[x]],dfn[x]);
}
if(dep[x]<dep[y]) swap(x,y);
ans+=t.query(,,n,dfn[y],dfn[x]);
return ans;
}
int main() {
scanf("%d",&n);
for(int i=;i<n;i++) {
int x,y;
scanf("%d%d",&x,&y);
add_edge(x,y);
}
dfs1();
dfs2();
int q;
scanf("%d",&q);
while(q--) {
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==) modify(x,y);
if(op==) printf("%d\n",query(x,y));
}
return ;
}
[CodeVS4633][Mz]树链剖分练习的更多相关文章
- Codevs 4633 [Mz]树链剖分练习
4633 [Mz]树链剖分练习 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description 给定一棵结点数为n的树,初始点权均为0,有依次q个 ...
- CODE[VS]4633:Mz树链剖分练习
Description 给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a= ...
- 树链剖分(+线段树)(codevs4633)
type node=^link; link=record des:longint; next:node; end; type seg=record z,y,lc,rc,toadd,sum:longin ...
- 2020牛客NOIP赛前集训营-提高组(第三场) C - 牛半仙的妹子Tree (树链剖分)
昨天教练问我:你用树剖做这道题,怎么全部清空状态呢? 我:???不是懒标记就完了??? 教练:树剖不是要建很多棵线段树吗,不止log个,你要一个一个清? 我:为什么要建很多棵线段树? ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...
随机推荐
- [转]数据对齐对CPU的影响
[转]http://www.cnblogs.com/wuzhenbo/archive/2012/06/05/2537465.html 1.前言 在IBM开发社区上发现一篇叫'Data alignmen ...
- Linux的capability深入分析(2)【转】
转自:https://blog.csdn.net/wangpengqi/article/details/9821231 rpm -ql libcap-2.16-5.2.el6.i686 /lib/l ...
- xpath与nodejs解析xml
测试xpath的工具 http://www.freeformatter.com/xpath-tester.html#ad-output http://www.xpathtester.com/test ...
- iptables实现网络防火墙及地址转换
iptables主机防火墙功能及常用命令 FSM:Finite State Machine 有限状态机 客户端:closed -->syn_sent -->established --&g ...
- lamp环境搭建之配置apache与fpm方式的php
配置apache-2.4.9与fpm方式的php-5.4.26 一.apache.MySQL的安装参考<编译安装lamp环境> http://blog.csdn.net/reblue520 ...
- servlet请求中的信息
在servlet中HttpServeltRequest中有一个方法getRequestURL() 假如我们平常输入的地址是:localhost/Demo1/TestServlet?hello=worl ...
- 内存分配方式,堆区,栈区,new/delete/malloc/free
1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数时 ...
- shell expect权威指南和实战
一.概述 我们通过Shell可以实现简单的控制流功能,如:循环.判断等.但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能.而expec ...
- Oracle 高级排序函数 和 高级分组函数
高级排序函数: [ ROW_NUMBER()| RANK() | DENSE_RANK ] OVER (partition by xx order by xx) 1.row_number() 连续且递 ...
- linux POSIX 信号量介绍
信号量一.什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)使用.多线程可以同时运行多个线程函数完成功能,但是对于共享数据如果不加以锁定,随意改变共享数据的值会发生 ...