poj2763(树链剖分)
题目链接:http://poj.org/problem?id=2763
题意:定一棵带边权的树,要求支持两种操作:
1)询问树中某两点间的距离。
2)修改某条边的权值。
分析:树链剖分,边权修改,路径求和,将树上信息映射到线段树上则是单点修改,区间求和。。。
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 10007
#define inf 0x3f3f3f3f
#define N 100010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
struct edge
{
int to,next;
edge(){}
edge(int to,int next):to(to),next(next){}
}e[N<<];
int head[N<<],tot;
int top[N];//top[v]表示v所在的重链的顶端节点
int fa[N];//父亲节点
int dep[N];//深度
int sz[N];//si[v]表示以v为根节点的子树的节点数
int son[N];//重儿子
int p[N];//p[v]表示v与其父亲节点的连边在线段树中的位置
int fp[N];//与p数组相反
int pos;//所有链构成的线段树总长度
int sum[N<<],E[N][];
void addedge(int u,int v)
{
e[tot]=edge(v,head[u]);
head[u]=tot++;
}
void init()
{
tot=;FILL(head,-);
pos=;FILL(son,-);
}
void dfs(int u,int f,int d)
{
sz[u]=;dep[u]=d;fa[u]=f;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].to;
if(v==f)continue;
dfs(v,u,d+);
sz[u]+=sz[v];
if(son[u]==-||sz[son[u]]<sz[v])son[u]=v;
}
}
void getpos(int u,int sp)
{
top[u]=sp;
p[u]=++pos;
fp[pos]=u;
if(son[u]==-)return;
getpos(son[u],sp);
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].to;
if(v!=son[u]&&v!=fa[u])
{
getpos(v,v);
}
}
}
void Pushup(int rt)
{
int ls=rt<<,rs=ls|;
sum[rt]=sum[ls]+sum[rs];
}
void update(int ps,int c,int l,int r,int rt)
{
if(l==r)
{
sum[rt]=c;
return;
}
int m=(l+r)>>;
if(ps<=m)update(ps,c,lson);
else update(ps,c,rson);
Pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
return sum[rt];
int m=(l+r)>>;
int res=;
if(L<=m)res+=query(L,R,lson);
if(m<R)res+=query(L,R,rson);
return res;
}
int lca(int u,int v)
{
int fu=top[u],fv=top[v];
int res=;
while(fu!=fv)
{
if(dep[fu]<dep[fv])
{
swap(fu,fv);swap(u,v);
}
res+=query(p[fu],p[u],,pos,);
u=fa[fu];fu=top[u];
}
if(dep[u]>dep[v])swap(u,v);
if(u!=v)
res+=query(p[son[u]],p[v],,pos,);
return res;
}
int main()
{
int n,t,s,u,v;
while(scanf("%d%d%d",&n,&t,&s)>)
{
init();
for(int i=;i<n;i++)
{
scanf("%d%d%d",&E[i][],&E[i][],&E[i][]);
addedge(E[i][],E[i][]);
addedge(E[i][],E[i][]);
}
dfs(,,);
getpos(,);
for(int i=;i<n;i++)
{
if(dep[E[i][]]>dep[E[i][]])
swap(E[i][],E[i][]);
update(p[E[i][]],E[i][],,pos,);
}
int op;
while(t--)
{
scanf("%d",&op);
if(!op)
{
scanf("%d",&u);
printf("%d\n",lca(s,u));
s=u;
}
else
{
scanf("%d%d",&u,&v);
update(p[E[u][]],v,,pos,);
}
}
}
}
poj2763(树链剖分)的更多相关文章
- poj2763树链剖分边权+区间和
自己写的比原来的板子常数小了不少嘻嘻,边权处理起来比点权要复杂一下 由于根节点没有被映射的边,其被访问到的顺序是0,直接排除在线段树外 #include<iostream> #includ ...
- poj2763 树链剖分(线段树)
注意这里都是把边放到线段树中,所以lca的时候,要注意如果top[x]==top[y] && x==y 的时候已经完成了. 仔细想想边和点的不同之处!!! #include<ma ...
- POJ2763 Housewife Wind 树链剖分 边权
POJ2763 Housewife Wind 树链剖分 边权 传送门:http://poj.org/problem?id=2763 题意: n个点的,n-1条边,有边权 修改单边边权 询问 输出 当前 ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
随机推荐
- Codility上的问题 (17) PI 2012
这个题比较简单,给定一个整数数组,对每个元素,求出和它最近比它大的数的距离(下标绝对值),如果没有比它大的数,认为距离是0. 数组元素个数 N [0..50000],数组元素范围[-10^9, +10 ...
- Java 实现观察者(Observer)模式
1. Java自带的实现 类图 /** * 观察目标 继承自 java.util.Observable * @author stone * */ public class UpdateObservab ...
- doT js模板入门
doT.js github地址: doT.js 官方站点 实例1:简单 <!DOCTYPE html> <html lang="en"> <head& ...
- java中遍历MAP,嵌套map的几种方法
java中遍历MAP的几种方法 Map<String,String> map=new HashMap<String,String>(); map.put("us ...
- xvfb 初步探究
有时候我们不关注程序是否有界面(比如自动化测试),只要程序在运行就可以了 很感谢 xvfb 这个工具给我们提供了相关的功能 比如在没有 X server 的机器上运行 gedit, 可以用下面的命令 ...
- uva 357 Let Me Count The Ways(01背包)
题目连接:357 - Let Me Count The Ways 题目大意:有5种硬币, 面值分别为1.5.10.25.50,现在给出金额,问可以用多少种方式组成该面值. 解题思路:和uva674是一 ...
- Greenplum同步到Oracle
开发提出须要从Greenplum同步到Oracle的解决方式,写了个脚本用于定时调度处理. #!/bin/sh #copy_gp_2_ora.sh if [ $# -ne 1 ]; then ...
- 随想录(关于ucore)
[ 声明:版权全部,欢迎转载.请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 之前用过一段时间skyeye,也对开发skyeye的陈渝有一些了解.近期在github上闲逛的 ...
- CSS——inline-block属性
Inline-block 是元素 display属性的一个值 .这个名字的由来是因为,可以简单的解释为inline+block :display设置这个值的元素,兼具行内元素( inline elem ...
- 并发编程实践五:ReentrantLock
ReentrantLock是一个可重入的相互排斥锁,实现了接口Lock,和synchronized相比,它们提供了同样的功能.但ReentrantLock使用更灵活.功能更强大,也更复杂.这篇文章将为 ...