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路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
随机推荐
- Inhouse interview(websense)
1.Tell me about yourself? My name is xxx,i 'm from xxx. now , I am a postgratuation and my major sub ...
- javascript 变量转义
$(this).append('<a href="2-1partner.html"><div><img width="645" h ...
- 5.单行函数,多行函数,字符函数,数字函数,日期函数,数据类型转换,数字和字符串转换,通用函数(case和decode)
1 多行函数(理解:有多个输入,但仅仅输出1个结果) SQL>select count(*) from emp; COUNT(*) ------------- 14 B 字符函数Lowe ...
- zipalign 文件路径问题
在使用zipalign,对Android程序进行打包,有些时候可能提示找不到zipalign ,可以复制一份放在相应的文件夹就行了 windows: 如果缺少zipalign,在网上找到相应的文件放在 ...
- 循环json数据的列
var len = json.length; for (var i = 0; i < len; i++) { for (obj in json[i]) { var obj2 = ...
- 移动端网页JS框架-手机触摸事件框架,日历框架带滑动效果
swiper.js,hammer.js,mobiscroll http://www.mobiscroll.com/ 日历
- boost计算随机数和计算crc32简单示例
boost计算随机数和计算crc32简单示例 - jwybobo2007的专栏 - 博客频道 - CSDN.NET boost计算随机数和计算crc32简单示例 2013-02-18 17:14 10 ...
- C++ Map 容器
1.Map是c++的一个标准容器,它提供了很好一对一的关系. Map是一种关联是容器,在map中增加和删除元素非常容易.可以修改一个特定的节点而不对其他节点不产生影响,由于map是一种关联式容器,Ke ...
- python中使用ctypes调用MinGW生成的动态链接库(dll)
关于gcc编译dll的我就不说了,网上举例一大堆,下面以g++为例. 假设有一个test.cpp文件如下: extern "C" { __declspec(dllexport) d ...
- golang使用pprof检查goroutine泄露
有一段时间,我们的推送服务socket占用非常不正常,我们自己统计的同一时候在线就10w的用户,可是占用的socket居然达到30w,然后查看goroutine的数量,发现已经60w+. 每一个用户占 ...