Poj--2763(树链剖分,线段树,处理边)

2014-10-06 22:08:46
思路:一道裸的树剖,线段树维护的是边,所以姿势稍有不同。建树的过程不用另开Build函数,而使用Update将边一条一条更新进树中。

  要注意!线段树中第 i 个叶子节点存的是第 i - 1条边。(这样就使得第一条边为根节点与其父节点的边,是虚的边)

  1 /*************************************************************************
  2     > File Name: 2763.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com
  5     > Created Time: Sun 05 Oct 2014 06:39:02 PM CST
  6 ************************************************************************/
  7 
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <cmath>
 12 #include <vector>
 13 #include <map>
 14 #include <set>
 15 #include <queue>
 16 #include <iostream>
 17 #include <algorithm>
 18 using namespace std;
 19 #define lp (p << 1)
 20 #define rp (p << 1|1)
 21 #define getmid(l,r) (l + (r - l) / 2)
 22 #define MP(a,b) make_pair(a,b)
 23 typedef long long ll;
 24 const int INF = 1 << 30;
 25 const int maxn = 100010;
 26 
 27 int n,q,s;
 28 int first[maxn],next[maxn << 1],ver[maxn << 1],ecnt;
 29 int dep[maxn],sz[maxn],son[maxn],fa[maxn],top[maxn],w[maxn],aw[maxn],tsz;
 30 int e[maxn][3],sum[maxn << 2];
 31 
 32 void Init(){
 33     memset(first,-1,sizeof(first));
 34     ecnt = 0;
 35     tsz = -1;
 36 }
 37 
 38 void Add_edge(int u,int v){
 39     next[++ecnt] = first[u];
 40     ver[ecnt] = v;
 41     first[u] = ecnt;
 42 }
 43 
 44 void Dfs(int p,int pre,int d){
 45     sz[p] = 1;
 46     dep[p] = d;
 47     son[p] = -1;
 48     fa[p] = pre;
 49     int tmp = 0,v;
 50     for(int i = first[p]; i != -1; i = next[i]) if((v = ver[i]) != pre){
 51         Dfs(v,p,d + 1);
 52         if(sz[v] > tmp){
 53             tmp = sz[v];
 54             son[p] = v;
 55         }
 56         sz[p] += sz[v];
 57     }
 58 }
 59 
 60 void Dfs_pos(int p,int tp){
 61     w[p] = ++tsz;
 62     aw[tsz] = p;
 63     top[p] = tp;
 64     if(son[p] != -1) Dfs_pos(son[p],tp);
 65     for(int i = first[p]; i != -1; i = next[i]){
 66         int v = ver[i];
 67         if(v != son[p] && v != fa[p])
 68             Dfs_pos(v,v);
 69     }
 70 }
 71 
 72 int Query_sum(int a,int b,int p,int l,int r){
 73     if(a <= l && r <= b)
 74         return sum[p];
 75     int mid = getmid(l,r),res = 0;
 76     if(a <= mid) res += Query_sum(a,b,lp,l,mid);
 77     if(b > mid) res += Query_sum(a,b,rp,mid + 1,r);
 78     return res;
 79 }
 80 
 81 int Find(int a,int b){
 82     int f1 = top[a],f2 = top[b];
 83     int res = 0;
 84     while(f1 != f2){
 85         if(dep[f1] > dep[f2]){
 86             swap(a,b);
 87             swap(f1,f2);
 88         }
 89         res += Query_sum(w[f2],w[b],1,1,tsz);
 90         b = fa[f2];
 91         f2 = top[b];
 92     }
 93     if(a == b) return res;
 94     if(dep[a] > dep[b]) swap(a,b);
 95     res += Query_sum(w[son[a]],w[b],1,1,tsz);
 96     return res;
 97 }
 98 
 99 void Update_tree(int a,int c,int p,int l,int r){
100     if(l == r){
101         sum[p] = c;
102         return;
103     }
104     int mid = getmid(l,r);
105     if(a <= mid) Update_tree(a,c,lp,l,mid);
106     else Update_tree(a,c,rp,mid + 1,r);
107     sum[p] = sum[lp] + sum[rp];
108 }
109 
110 int main(){
111     int a,b,c,f;
112     Init();
113     scanf("%d%d%d",&n,&q,&s);
114     for(int i = 1; i < n; ++i){
115         scanf("%d%d%d",&a,&b,&c);
116         Add_edge(a,b);
117         Add_edge(b,a);
118         e[i][0] = a,e[i][1] = b,e[i][2] = c;
119     }
120     Dfs(1,0,0);
121     Dfs_pos(1,1);
122     for(int i = 1; i < n; ++i){
123         if(dep[e[i][0]] > dep[e[i][1]]) swap(e[i][0],e[i][1]);
124         Update_tree(w[e[i][1]],e[i][2],1,1,tsz);
125     }
126     for(int i = 1; i <= q; ++i){
127         scanf("%d",&f);
128         if(f == 0){
129             scanf("%d",&a);
130             printf("%d\n",Find(a,s));
131             s = a;
132         }
133         else{
134             scanf("%d%d",&a,&c);
135             Update_tree(w[e[a][1]],c,1,1,tsz);
136         }
137     }
138     return 0;
139 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4008772.html

Hypermesh静力学仿真分析与模态分析-02 hypermesh中对较复杂实体进行静力学分析和模态分析,包含材料属性添加,载荷设置等等 阅读详情

相关推荐

poj 2763 housewife Wind

poj 2763 程序 线段树 LCA 2000MS AC

poj 2763(树链剖分)

题意:有一个人在一棵树的某个节点s,然后给出了树的每条都有一个权值,有两种操作,0 a 是问从节点s到a的路径权值和,然后a就成了s,1 a b把第a条权值变为b。 题解:权转点权的模板题。#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100005; s

俯瞰风景 1074

博尔特地铁刷刀体制pak(无需root) (1).zip

博尔特地铁刷刀体制pak(无需root) (1).zip

POJ 2763:Housewife Wind(树链剖分

http://poj.org/problem?id=2763 题意:给出 n 个点, n-1 条带权, 询问是询问 s 到 v 的权值, 修改是修改存储时候的第 i 条的权值。 思路:树链剖分之修改权。权的修改, 与点权修改不同的地方在于, 线段树中存的点是,其中每条是以 儿子 的时间戳来记录的。例如: u -> v , dep[u] < dep[v], 说明 u 是...

weixin_30376083的博客 128

POJ2763(树链剖分权,模板)

题意:给定一个树形图,某人原来在 s 点,每条(路)有通过的时间花费,有两种操作:1. 查询某人到 u 点花费的时间 2. 更新某条路的时间花费。 解题思路:前面树链剖分练得一直是点权,但一遇权懵逼了。下里面的代码是从点权改过来的。其实权和点权是差不多的。大致意思就是,取每条连个点中,处于下位的(更深)点来记录这条的值。有一些查询时的细节和点权稍有不同,详见代码注释。 #inclu...

qq_39861441的博客 296

POJ 2763 Housewife Wind

POJ_2763     用link-cut-tree或者树链剖分都可以,只要支持单点修改和区间求和就可以了。但后面看dicuss里面说是树状数组和LCA,但由于这两个东西我暂时都没研究过,所以就没再深究这种解法了。 #include&lt;stdio.h&gt; #include&lt;string.h&gt; #define MAXD 100010 #define MAXM 20...

weixin_33913332的博客 84

POJ 2763树剖+线段树+树状数组

代码分享

Free Loop~~~跳动的音符 417

POJ-2763 树链剖分 线段树

题目 把权看作点权 不知道为啥N=1e5+5会wa,数组要开大点 #include<iostream> #include<string.h> #include<stdio.h> using namespace std; const int N=2e5+5; int fa[N],son[N],dep[N],top[N],siz[N],pos[N],fp[N]; ...

刷题记录 204

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

题目链接:http://poj.org/problem?id=2763 题目大意:某人初始在s点。有q次移动,每次移动沿着树上一条链,每经过一条有一定花费,这个花费可以任意修改。问每次移动的花费。 解题思路: 树链剖分基础题。每次Q之后改变一下s。 线段树记录的是权。方法是对于一条(u,v)权值加在dep比较大的那一端。 链查询()和 链查询(点)在轻链时略有不同。 注意本...

weixin_34101784的博客 153

POJ 2763 Housewife Wind (树链剖分+线段树)

题目链接:POJ 2763 Housewife Wind 题意:抽象出来就是 一棵已知节点之间的权,两个操作,1·修改权,2·询问两个节点之间的权和。 AC代码: #include #include #include using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<

n-1 896

poj2763 Housewife Wind 树链剖分

题意:给定树的结点数n,初始起点s,有两个操作,(1) 0 u 查询从当前位置到u的时间,当前位置变为u  (2) 1 i w 修改第i条路花的 时间为w。 思路:树链剖分。剖分完,线段树单点更新,区间查询。详见代码: /********************************************************* file name: poj2763.cpp a

AC_kereo的专栏 1111

树链剖分入门 poj 2763

题目链接:题目 修改权,查询两点间距离,树链剖分,按权建树,线段树维护即可。 代码: /* *********************************************** Author :xianxingwuguan Created Time :2014/1/15 21:27:00 File Name :4.cpp **************************

_rabbit的专栏 921

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

POJ.2763 Housewife Wind ( 树链剖分 线段树维护区间和 )题意分析给出n个点,m个询问,和当前位置pos。 先给出n-1条,u->v以及权w。 然后有m个询问,询问分2种: 一是讲第i条权修改为w。 二是询问从当前位置走到点x经过的权和(下次询问就是从这点开始)权的树链剖分,其实和点权的差不多。对于一条u-v,及其权w,在建立线段树的时候,将深

Pengwill's Blog 505

树链剖分 - poj2763 Housewife Wind

题目: http://poj.org/problem?id=2763 题意: 给定一棵树,及一个初始位置,然后给出q个操作,每个操作为改变某根树枝权值,或求树上两点之间的距离 思路: 树链剖分的模板题,权值位于上,剖分完用线段树存储查询即可,注意此时线段上每个单结点K的权值定义为结点K到其父节点的距离 代码: #include #include #inc

Keith_windniw的专栏 499

POJ 2763 Housewife Wind 树链剖分

题目大意: 就是给出一棵树然后p次操作, 每次操作询问从当前位置到某个位置的路径的权值和, 另外一个操作是修改某条的权值 大致思路: 树链剖分第二题... 因为写线段树的在建树的时候没有pushUp调试了一个小时才发现....感觉自己智商好捉急..... 不过因为这个原因对于树链剖分的过程更熟悉了... 首先在处理的时候, 我们先将上的信息转移到点上, 这里我们将所有的

Gatevin的专栏 415

POJ2763 树链剖分

题目:POJ2763单点修改,区间查询(对进行操作) 0是查询从当前点到某个点的路程 1是修改某条的值 建好树以后把每个赋到它下面那个节点处就行了 貌似得手工扩栈,我也没扩栈 这道题好像卡vector,我用vector写的3600+ms,这个邻接表写的1000+ms#include <cstdio> #include <iostream> #include <algorithm> #

zlc1114的博客 316

|poj 2763|LCA, 树状数组|或者|树链剖分, 线段树|Housewife Wind

poj 2763LCA+树状数组/线段树。首先本题大致一看就是一个LCA,但是本题有操作更改某的权,这样会使得原本的far数组变化,不难发现,更改权后影响该下面所有点的答案。此时可以在LCA的DFS预处理时求出DFS序列(即时间戳),找到每个点管辖的范围,修改权相当于修改该连接的两个点深度深的那个点所管辖的范围,此时修改可以用暴力,但是由于far数组与LCA本身查询无关,我们可以用数据结构

博客停更,请到"再见,CSDN"文章中找新博客地址 804

POJ2763-LCA在线算法+树状数组

#include #include #include #include #include using namespace std; const int NN=210000; int n,en,c[NN],head[NN]; struct Edge{ int v,w,next; Edge() {} Edge(int _v,int _w,int _next): v

Wo xi Meiz 1445

POJ-2763-Housewife Wind(LCA+dfs序线段树

题目链接:POJ-2763-Housewife Wind有权修改的树中两点距离查询。 因为有权修改,所以用线段树维护到根的序列。 LCA求距离。 这题有个坑点就是不能用vector#include<cstdio> #include<cstring> #include<vector> using namespace std; const int maxn=1e5+7; int a[maxn]

On the way 557

[树链剖分]POJ2763 Housewife Wind

  原题链接: https://vjudge.net/problem/POJ-2763 题意: 维护一个树,权值在上,支持单点更新和区间查询操作。   题解: 树链剖分的模板题,只不过把点权换成了权,因为树每个点头上只有一条,所以可以把权映射到它的深度较深的那个点上,然后就套上模板就好了。 总结: 虽然是个模板提,但是还是wa到怀疑人生。 首先我开始是用mp[mk(u,...

a670531899的博客 2877
上一篇: Hdu--5060(数学)
下一篇: CF #271 div2
dingdi3021
博客等级 码龄10年 1粉丝 230原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值