注意这里都是把边放到线段树中,所以lca的时候,要注意如果top[x]==top[y] && x==y 的时候已经完成了。

仔细想想边和点的不同之处!!!

#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000007
#define mod 100000000
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN = ;
struct node
{
int to;
int val;
int next;
}edge[MAXN*];
int a[MAXN][];
int fa[MAXN],pre[MAXN],ind,w[MAXN],top[MAXN],siz[MAXN],son[MAXN],deq[MAXN],cnt;//w[]表示它和他父亲的连线在线段树种的位置
int vis[MAXN],n,m,tree[MAXN<<];
void add(int x,int y,int z)
{
edge[ind].to = y;
edge[ind].val = z;
edge[ind].next = pre[x];
pre[x] = ind++;
}
void dfs1(int rt,int pa,int d)
{
vis[rt] = ;
siz[rt] = ;
son[rt] = -;
deq[rt] = d;
fa[rt] = pa;
for(int i = pre[rt]; i != -; i = edge[i].next){
int t = edge[i].to;
if(!vis[t]){
dfs1(t,rt,d+);
siz[rt] += siz[t];
if(siz[t] > siz[son[rt]]){
son[rt] = t;
}
}
}
}
void dfs2(int rt,int tp)
{
vis[rt] = ;
w[rt] = ++ cnt;
top[rt] = tp;
if(son[rt] != -){
dfs2(son[rt],tp);
}
for(int i = pre[rt]; i != -; i = edge[i].next){
int t = edge[i].to;
if(!vis[t] && t != son[rt]){
dfs2(t,t);
}
}
}
void pushup(int rt)
{
tree[rt] = tree[rt<<] + tree[rt<<|];
}
void updata(int p,int val,int l,int r,int rt)
{
if(l == r){
tree[rt] = val;
return ;
}
int m = (l + r) >> ;
if(m >= p){
updata(p,val,lson);
}
else {
updata(p,val,rson);
}
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R){
return tree[rt];
}
int m = (l + r) >> ;
int ans = ;
if(m >= L){
ans += query(L,R,lson);
}
if(m < R){
ans += query(L,R,rson);
}
return ans;
}
int lca(int x,int y)
{
int ans = ;
while(top[x] != top[y]){
if(deq[top[x]] < deq[top[y]]){
swap(x,y);
}
ans += query(w[top[x]],w[x],,cnt,);
x = fa[top[x]];
}
if(x == y){//同一点没有边,仔细想想这就是为什么边和点的不同地方!
return ans;
}
if(deq[x] < deq[y]){
swap(x,y);
} ans += query(w[son[y]],w[x],,cnt,);//既然top[x] == top[y]说明x 和 y在同一条重边上 所以son[y]也在该路径上
//并且是树根的孩子,又w[]表示该点和其父亲相连的点的边在线段树中的编号,
//所以需要这步,这样能得出答案。
return ans;
}
int main()
{
int s,p;
while(~scanf("%d%d%d",&n,&p,&s)){
int x,y,z;
ind = ;
memset(pre,-,sizeof(pre));
for(int i = ; i < n; i++){
scanf("%d%d%d",&a[i][],&a[i][],&a[i][]);
add(a[i][],a[i][],a[i][]);
add(a[i][],a[i][],a[i][]);
}
memset(vis,,sizeof(vis));
dfs1(,,);//求deq siz son fa cnt = ;
memset(vis,,sizeof(vis));
dfs2(,);//求top w
memset(tree,,sizeof(tree));
for(int i = ; i < n; i++){
if(deq[a[i][]] < deq[a[i][]]){//让a[i][0]在下面
swap(a[i][],a[i][]);
}
updata(w[a[i][]],a[i][],,cnt,);//将a[i][0]和他父亲相连的边插入到线段树中
}
int q;
while(p--){
scanf("%d",&q);
if(q == ){
scanf("%d",&x);
printf("%d\n",lca(s,x));
s = x;
}
else {
scanf("%d%d",&x,&y);
updata(w[a[x][]],y,,cnt,);
}
}
}
return ;
}

poj2763 树链剖分(线段树)的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

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

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  6. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  7. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  10. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. eclipse菜单解释及中英对照

    在使用Eclipse作为开发工具的时候,建议使用英文版本的(直接百度从官网下就行,这里不详细描述,如果有问题,咱们私聊).虽然中文版本的对于和我一样对英文是小白的看起来特别爽,但是公司大多是英文版本的 ...

  2. RabbitMQ 一二事(4) - 路由模式介绍

    路由模式其实和订阅模式差不多,只不过交换机的类型不同而已 路由模式可以用下图来表示,比订阅模式多了一个key,举个栗子就是根据不同的人群来订阅公众号,来收取消息 根据不同的key来获取不同的消息 最简 ...

  3. 【C#】窗体动画效果

    通过调用API可以实现C#窗体的动画效果,主要调用user32.dll的行数AnimateWindow 1.函数申明 [System.Runtime.InteropServices.DllImport ...

  4. Linux内核

    Linux内核配置.编译及Makefile简述 Hi,大家好!我是CrazyCatJack.最近在学习Linux内核的配置.编译及Makefile文件.今天总结一下学习成果,分享给大家^_^ 1.解压 ...

  5. Java开发环境的搭建

    确定自己的操作系统版本并下载安装JDK 1.下载JDK windows系统: 右键我的电脑->属性;如下图: 2.下载JDK 下载地址:http://www.oracle.com/index.h ...

  6. IBatisNet基础组件

    DomSqlMapBuilder DomSqlMapBuilder,其作用是根据配置文件创建SqlMap实例.可以通过这个组件从Stream, Uri, FileInfo, or XmlDocumen ...

  7. [CareerCup] 9.6 Generate Parentheses 生成括号

    9.6 Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-p ...

  8. Windows 2008如何绑定MAC防范ARP攻击!

    Windows 2008如何绑定MAC防范ARP攻击!   阅读(1974)暂无评论时间:2010-11-23 22:52:13   在Windows server 2003时代,通过arp 这命令即 ...

  9. HoloLens开发手记 - Unity之Keyboard input 键盘输入

    虽然HoloLens支持很多种输入方式,包括蓝牙键盘在内.但是大部分应用还是不能断定用户有物理键盘可以输入,所以虚拟键盘输入还是必须要提供的. Unity提供了一个TouchScreenKeyboar ...

  10. 【MPI学习2】MPI并行程序设计模式:对等模式 & 主从模式

    这里的内容主要是都志辉老师<高性能计算之并行编程技术——MPI并行程序设计> 书上有一些代码是FORTAN的,我在学习的过程中,将其都转换成C的代码,便于统一记录. 这章内容分为两个部分: ...