注意这里都是把边放到线段树中,所以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. 【温故而知新-Javascript】图片效果(图像震动效果、闪烁效果、自动切换图像)

    1.当鼠标指针经过图像时图像震动效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  2. 分享一个解决MySQL写入中文乱码的方法

    分享一个解决MySQL写入中文乱码的方法 之前有发帖请教过如何解决MySQL写入中文乱码的问题.但没人会,或者是会的人不想回答.搜索网上的答案并尝试很多次无效,所以当时就因为这个乱码问题搁浅了一个软件 ...

  3. jQuery对象与dom对象的区别与相互转换

    什么是jQuery对象? 就是通过jQuery包装DOM对象后产生的对象.jQuery对象是jQuery独有的,其可以使用jQuery里的方法.例如: $("#test").htm ...

  4. 集合框架学习笔记<二>

    1.什么是ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处: 动态的增加和减少元素 实现了ICollection和ILis ...

  5. jQuery的无new实例化

    我只能说想法很好,设计的巧妙.看代码: var jQuery = function( selector, context ) { //执行了init函数并返回jQuery实例 return new j ...

  6. javascript设置网页刷新或者重新加载后滚动条的位置不变

    有个同事说再javascript中你可以做任何你想做的事情,当时觉得不以为然,今天遇到个问题,就是页面重新加载后总是回到页面的顶部,如果客户只想看到他想看到的部分是怎么变化的,这个体验就好了.原本想象 ...

  7. Javascript中的delete

    一.问题的提出 我们先来看看下面几段代码,要注意的是,以下代码不要在浏览器的开发者工具(如FireBug.Chrome Developer tool)中运行,原因后面会说明: 为什么我们可以删除对象的 ...

  8. mybatis-config.xml详解

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...

  9. 【CSS】css网页背景图片设置

    刚学CSS,了解了下网页背景图设置,顺便记录下. 下面主要是实现背景图位置保持不变,即不随滚动条动而动的功能. body { background-image:url(images/bck.png); ...

  10. Android启停调试

    环境配置 java jdk android sdk eclipse + adt 参考资料: http://tools.android-studio.org/#userconsent# android ...