题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值。

 #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 100010
#define ls o<<1
#define rs o<<1|1
#define define_m int m=(l+r)>>1
#define ll long long int first[N] , k; struct Edge{
int x , y , next , w;
Edge(){}
Edge(int x , int y , int next , int w):x(x),y(y),next(next),w(w){}
}e[N<<]; void add_edge(int x , int y , int w)
{
e[k] = Edge(x , y , first[x] , w);
first[x] = k++;
} int sz[N] , fa[N] , son[N] , dep[N] , id[N] , top[N] , num; void dfs(int u , int f , int d)
{
sz[u] = , fa[u] = f , dep[u] = d , son[u]=;
int maxn=;
for(int i=first[u] ; ~i ; i=e[i].next){
int v = e[i].y;
if(v == f) continue;
dfs(v , u , d+);
sz[u] += sz[v];
if(sz[v]>maxn) maxn=sz[v] , son[u]=v;
}
} void dfs1(int u , int f , int head)
{
top[u] = head;
id[u] = ++num;
if(son[u]){
dfs1(son[u] , u , head);
}
for(int i=first[u] ; ~i ; i=e[i].next){
int v = e[i].y;
if(v == f || v == son[u]) continue;
dfs1(v , u , v);
}
} int n , q , src , val[N] , sum[N<<]; void push_up(int o)
{
sum[o] = sum[ls]+sum[rs];
} void build(int o , int l , int r)
{
if(l==r){
sum[o] = val[l];
return;
}
define_m;
build(ls , l , m);
build(rs , m+ , r);
push_up(o);
} void update(int o , int l , int r , int p , int v)
{
if(l==r){
sum[o] = v;
return;
}
define_m;
if(m>=p) update(ls , l , m , p , v);
else update(rs , m+ , r , p , v);
push_up(o);
} int query(int o , int l , int r , int s , int t)
{
if(l>=s && r<=t) return sum[o];
define_m;
int ans = ;
if(m>=s) ans+=query(ls , l , m , s , t);
if(m<t) ans+=query(rs , m+ , r , s , t);
return ans;
} int calPath(int u , int v)
{
int top1 = top[u] , top2 = top[v];
int ans = ;
while(top1!=top2){
if(dep[top1]<dep[top2]){
swap(top1 , top2);
swap(u , v);
}
ans += query( , , num , id[top1] , id[u]);
// cout<<"range: "<<id[top1]<<" "<<id[u]<<" "<<ans<<endl;
u = fa[top1];
top1 = top[u];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u , v);
ans += query( , , num , id[son[v]] , id[u]);
}
return ans;
} int main()
{
// freopen("in.txt" , "r" , stdin);
while(~scanf("%d%d%d" , &n , &q , &src)){
memset(first , - , sizeof(first));
k = ;
for(int i= ; i<n- ; i++){
int u , v , w;
scanf("%d%d%d" , &u , &v , &w);
add_edge(u , v , w);
add_edge(v , u , w);
}
num = ;
dfs( , , );
dfs1( , , );
// for(int i=1 ; i<=n ; i++) cout<<i<<" "<<son[i]<<" "<<id[i]<<endl;
for(int i= ; i<n- ; i++){
int j = i<<;
if(fa[e[j].x] != e[j].y) val[id[e[j].y]] = e[j].w;
else val[id[e[j].x]] = e[j].w;
}
build( , , num);
int en , op , t;
while(q--){
scanf("%d" , &op);
if(op){
scanf("%d%d" , &t , &en);
t--;
int pos;
if(fa[e[t*].x] != e[t*].y) pos = id[e[t*].y];
else pos = id[e[t*].x];
// cout<<"update: "<<pos<<endl;
update( , , num , pos , en);
}
else{
scanf("%d" , &en);
int ans = calPath(src , en);
printf("%d\n" ,ans);
src = en;
}
}
}
return ;
}

POJ 2763的更多相关文章

  1. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  2. POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新

    题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为 ...

  3. POJ 2763 Housewife Wind(DFS序+LCA+树状数组)

    Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11419   Accepted: 3140 D ...

  4. poj 2763 Housewife Wind(树链拆分)

    id=2763" target="_blank" style="">题目链接:poj 2763 Housewife Wind 题目大意:给定一棵 ...

  5. B - Housewife Wind POJ - 2763 树剖+边权转化成点权

    B - Housewife Wind POJ - 2763 因为树剖+线段树只能解决点权问题,所以这种题目给了边权的一般要转化成点权. 知道这个以后这个题目就很简单了. 怎么转化呢,就把这个边权转化为 ...

  6. POJ 2763 (树链剖分+边修改+边查询)

    题目链接:http://poj.org/problem?id=2763 题目大意:某人初始在s点.有q次移动,每次移动沿着树上一条链,每经过一条边有一定花费,这个花费可以任意修改.问每次移动的花费. ...

  7. POJ 2763:Housewife Wind(树链剖分)

    http://poj.org/problem?id=2763 题意:给出 n 个点, n-1 条带权边, 询问是询问 s 到 v 的权值, 修改是修改存储时候的第 i 条边的权值. 思路:树链剖分之修 ...

  8. POJ 2763 Housewife Wind (树链剖分 有修改单边权)

    题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...

  9. poj 2763 Housewife Wind (树链剖分)

    题目链接:http://poj.org/problem?id=2763 题意: 给定一棵含n个结点的树和树的边权,共有q次操作,分为两种 0 c :求从位置s到c的距离,然后s变成c 1 a b:把第 ...

  10. poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询

    /** problem: http://poj.org/problem?id=2763 **/ #include<stdio.h> #include<stdlib.h> #in ...

随机推荐

  1. Object Pascal 控制语句

    控制语句 1.常量声明语句常量在声明时就被赋予了一个值,在程序执行过程中是不可改变的. 格式 const 常量名 :数据类型 = 值 下面的例子声明了3 个常量: const Pi = 3.14159 ...

  2. iOS 的 Safari 文件上传功能详解

    iOS 6 给 Safari 浏览器带来的另外一个功能是文件上传,终于 Safari 终于支持 input 输入框的文件类型了,并且还支持 HTML媒体捕获(HTML Media Capture). ...

  3. HTML的超链接

    一.超链接概念: 超链接也叫 URL 中文翻译为资源定址器.这个定址器的功能主要告诉浏览器根据 URL的地址找到所需的资源.作用于连接资源 二.超链接的常用属性: 1.href=指定目的地,当有了hr ...

  4. Sqlserver_In、exists使用

    in是把外表和内表作hash 连接,而exists 是对外表作loop 循环,每次loop 循环再对内表进行查询. 一直以来认为exists 比in 效率高的说法是不准确的.如果查询的两个表大小相当, ...

  5. nfs服务器设置

    前段时间重新装了一下Linux系统,结果导致NFS服务器总是挂在不成功,于是粗略学习了一下: NFS服务需要两个软件包: 1.nfs-utiles-* 2.portmap-* nfsd:它是基本的NF ...

  6. javascript算术运算符详解

    算术运算符 +.-.*./.%.++.-- ++.--分为前缀形式和后缀形式 前缀形式先加减1在执行 后缀形式先执行再加减1 注意 +号用来连接两个字符串 只要+连接的操作数中有一个是字符串型,JS就 ...

  7. 解决xshell 中文乱码

    在xshell命令行里面 输入:  locale输出: LANG=zh_CN.UTF-8LC_CTYPE="zh_CN.UTF-8"LC_NUMERIC="zh_CN.U ...

  8. Docker 使用指南 (二)—— 搭建本地仓库

    版权声明:本文由田飞雨原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/94 来源:腾云阁 https://www.qclou ...

  9. Ubuntu 下 Neo4j单机安装和集群环境安装

    1. Neo4j简介 Neo4j是一个用Java实现的.高性能的.NoSQL图形数据库.Neo4j 使用图(graph)相关的概念来描述数据模型,通过图中的节点和节点的关系来建模.Neo4j完全兼容A ...

  10. hdu---1506(Largest Rectangle in a Histogram/dp最大子矩阵)

    Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...