注意这里都是把边放到线段树中,所以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. 基于对话框的MFC应用程序基本结构

    新建一个基于对话框的MFC应用程序,假设命名为 Test:则该应用程序在刚创建的时候,有4个非常重要的文件和3个类: 4个非常重要的文件 1.Test.h 2.Test.cpp (应用程序类头文件) ...

  2. HDU 1850 Being a Good Boy in Spring Festival

    此题先考虑第一种,5 7 9的情况,先手如果想赢,则必定要把异或值变为0,因为随便取,所以此处的异或指的是对堆中的石子数进行异或,而非异或其SG函数. 首先7^9=14,因为要异或为0,则5要变成14 ...

  3. Bluestacks 使用

    Bluestack介绍 一款能够在PC模拟Android的好用模拟器 官网:http://www.bluestacks.cn/ 早在2012年就使用上它了,但一直未发现他的许多优点,在使用过其它的两款 ...

  4. Java Executor并发框架(三)ThreadPoolExecutor 队列缓存策略

    前面两篇讲解了线程池中线程创建后的运行情况,其中有一系列的策略来保证线程正常运行.但是我们知道线程池是可以设置容量的,而且这容量的设置也是至关重要的,如果容量设置的太小,那么将会影响系统的运行效率,如 ...

  5. java9-3 返回类型

    1. 返回值类型 基本类型:(基本类型简单) 引用类型: 类:返回的是该类的对象 class Student2 { public void study() { System.out.println(& ...

  6. js模拟手机触摸屏

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  7. HTML---总结

    (1) margin负值能让没有宽度的盒子变大. 对于有宽度的盒子,没有浮动,只有margin-top 和margin-left 有效:如果浮动,margin-浮动方向 有效,-top有效,margi ...

  8. Java 操作 Redis 高级

    /Users/sherry/WorkPath/Git/Web/redisDemo/src/main/java/org/zln/utils/JedisUtils.java package org.zln ...

  9. 【转】Bresenham快速画直线算法

    一.             算法原理简介: 算法原理的详细描述及部分实现可参考: http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresen ...

  10. shell小结

    一 判断 -d 测试是否为目录.-f 判断是否为文件. -s 判断文件是否为空 如果不为空 则返回0,否则返回1 -e 测试文件或目录是否存在. -r 测试当前用户是否有权限读取. -w 测试当前用户 ...