思路:

轻重链剖分+线段树。

 #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]树链剖分练习的更多相关文章

  1. Codevs 4633 [Mz]树链剖分练习

    4633 [Mz]树链剖分练习 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description 给定一棵结点数为n的树,初始点权均为0,有依次q个 ...

  2. CODE[VS]4633:Mz树链剖分练习

    Description 给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a= ...

  3. 树链剖分(+线段树)(codevs4633)

    type node=^link; link=record des:longint; next:node; end; type seg=record z,y,lc,rc,toadd,sum:longin ...

  4. 2020牛客NOIP赛前集训营-提高组(第三场) C - 牛半仙的妹子Tree (树链剖分)

    昨天教练问我:你用树剖做这道题,怎么全部清空状态呢?    我:???不是懒标记就完了???    教练:树剖不是要建很多棵线段树吗,不止log个,你要一个一个清?    我:为什么要建很多棵线段树? ...

  5. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  6. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  7. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  8. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  9. 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)

    题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...

随机推荐

  1. [Shell]获取IP地址

    ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | cut -c 6- ifconfig eth1 | grep &quo ...

  2. kafka系列三、Kafka三款监控工具比较

    转载原文:http://top.jobbole.com/31084/ 通过研究,发现主流的三种kafka监控程序分别为: Kafka Web Conslole Kafka Manager KafkaO ...

  3. Account的简单架构

    前几天,有园友私下问我,博客中的AccountDemo后端架构为什么是那样的,是不是分层太多太冗余,故这里简单介绍下.先看解决方案工程截图: 每个工程的含义,见https://www.cnblogs. ...

  4. 大型NodeJS项目架构与优化

    使用场景: proxy(API冗余,跨域) vue ssr(服务端渲染) socket(大并发,通讯) 区块链(创业公司,新兴行业) 讨论什么? NodeJS异步IO原理及优化方案 NodeJS内存管 ...

  5. JUnit单元测试--IntelliJ IDEA

    单元测试的基本使用 一.环境配置 使用idea IDE 进行单元测试,首先需要安装JUnit 插件. 1.安装JUnit插件步骤 File-->settings-->Plguins--&g ...

  6. Java基础93 JDBC连接MySQL数据库

    本文知识点(目录): 1.什么是jdbc     2.jdbc接口的核心API     3.使用JDBC技术连接MySQL数据库的方法    4.使用Statement执行sql语句(DDL.DML. ...

  7. TStringList 复制 赋值。

    方法1:list2.addstrings(list1) 特点是:不会清空list2中原有的数据. 方法2:list2.assign(list1) 特点是:会清空list2中原有的数据(直接替换链表节点 ...

  8. PHP实现字符串转义和还原

    首先大家可以简单了解下什么是转义字符?有什么用? 转义字符是一种特殊的字符常量.转义字符以反斜线"\"开头,后跟一个或几个字符.转义字符具有特定的含义,不同于字符原有的意义,故称“ ...

  9. cf220B莫队

    用莫队比直接做快了很多.. #include<iostream> #include<cstring> #include<cstdio> #include<cm ...

  10. 性能测试二十一:环境部署之mysql

    在正常工作中,mysql应该部署到 一台独立的服务器上,不与tomcat共用服务器,由于成本原因,现部署到一起 为避免出错引起麻烦,先备份: 一:环境清理:先卸载系统自带的mysql 停止mysql: ...