poj 2763 Housewife Wind (LCA转RMQ+树状数组)
来源:互联网 发布:学蒙古语软件下载 编辑:程序博客网 时间:2024/06/06 00:16
题意:给一棵树,两种操作:
1、求两点间路径长度
2、修改某条路径长度。
对于操作1,先求两点的LCA,设d[i]为结点i到根结点的距离,那么两点路径长度就等于d[u]+d[c]-2*d[lca(u,v)],求LCA可转化为RMQ来求。
对于操作2,考虑修改之后对操作1的影响,即修改之后,会使得以该边的某一个端点为根的子树中所有结点的d发生变化。
用L[u],R[u]分别表示结点u的dfs序、回溯到u时的dfs序,那么修改某一条边的时候,设该边dfs序较大的那个端点为u,则d受影响的顶点就是dfs序位于区间[L[u],R[u]]的所有顶点。因此可以考虑用树状数组(或者线段树之类的)来维护区间的值。对于每一个顶点的dfs序给予一个权值,初始化为0。每个顶点u其到根结点的距离为区间[0,L[u]]的和
对于每一条边i,设其dfs序较大的那个端点为G[i],每次更新的时候,将L[G[i]]的权值加上一个w(更新的值),R[G[i]]+1的权值减去一个w,这样,L[G[i]]~R[G[i]区间内的所有顶点在求和的时候和(即该结点到根的距离)都增加了w,而区间外的结点不受影响。
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<stack>#include<cmath>#include<queue>#include<vector>using namespace std;#define maxn 100001struct Edge{ int to,next,w;}edge[maxn<<1];int n,a[maxn],head[maxn],dep[maxn<<1],cnt,pos[maxn],E[maxn<<1],dfn,f[maxn<<1][20];int W[maxn],L[maxn],R[maxn],dfs_clock,C[maxn],G[maxn];inline void add(int u,int v,int w){ edge[cnt].to=v; edge[cnt].next=head[u]; edge[cnt].w=w; head[u]=cnt++;}inline int lowbit(int x){return (x)&(-x);}void init(){ memset(head,-1,sizeof(head)); memset(pos,-1,sizeof(pos)); memset(C,0,sizeof(C)); cnt=dfn=0; dfs_clock=0;}void dfs(int u,int deep){ E[dfn]=u,dep[dfn]=deep,pos[u]=dfn++; L[u]=++dfs_clock; for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; if(pos[v]==-1) { G[edge[i].w]=v; dfs(v,deep+1); E[dfn]=u,dep[dfn++]=deep; } } R[u]=dfs_clock;}void init_RMQ(int n){ for(int i=1;i<=n;++i) f[i][0]=i; for(int j=1;(1<<j)<=n;++j) for(int i=1;i+(1<<j)-1<=n;++i) { if(dep[f[i][j-1]]<dep[f[i+(1<<(j-1))][j-1]]) f[i][j]=f[i][j-1]; else f[i][j]=f[i+(1<<(j-1))][j-1]; }}inline int RMQ(int L,int R){ int k=0; while(1<<(k+1)<=R-L+1) ++k; if(dep[f[L][k]]<dep[f[R-(1<<k)+1][k]]) return f[L][k]; return f[R-(1<<k)+1][k];}inline int lca(int u,int v){ if(pos[u]>pos[v]) return E[RMQ(pos[v],pos[u])]; return E[RMQ(pos[u],pos[v])];}inline void update(int i,int x){ for(;i<=n;i+=lowbit(i)) C[i]+=x;}inline int sum(int i){ int s=0; for(;i>0;i-=lowbit(i)) s+=C[i]; return s;}int main(){ int i,u,v,k,q,w,s; while(~scanf("%d%d%d",&n,&q,&s)) { init(); for(i=1;i<n;++i) { scanf("%d%d%d",&u,&v,&w); add(u,v,i); add(v,u,i); W[i]=w; } dfs(1,0); init_RMQ(2*n-1); u=s; for(i=1;i<n;++i) { update(L[G[i]],W[i]); update(R[G[i]]+1,-W[i]); } while(q--) { scanf("%d",&k); if(k){ scanf("%d%d",&u,&w); update(L[G[u]],w-W[u]); update(R[G[u]]+1,-w+W[u]); W[u]=w; } else{ scanf("%d",&v); printf("%d\n",sum(L[s])+sum(L[v])-2*sum(L[lca(s,v)])); s=v; } } } return 0;}
0 0
- poj 2763 Housewife Wind (LCA转RMQ+树状数组)
- POJ 2763 Housewife Wind (LCA + 树状数组)
- POJ 2763 Housewife Wind (LCA+树状数组)
- poj 2763 Housewife Wind 【LCA 与 树状数组】
- poj 2763 Housewife Wind(RQM+树状数组)
- 【POJ 2763】Housewife Wind【LCA】
- |poj 2763|LCA, 树状数组|或者|树链剖分, 线段树|Housewife Wind
- POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新
- poj2763 Housewife Wind--LCA转RMQ
- POJ 2763 Housewife Wind [树链剖分(边权)+树状数组]【数据结构】
- poj 2763 Housewife Wind 树链剖分+LCA
- poj 2763 Housewife Wind 【LCA or 树链剖分】
- POJ - 2763 Housewife Wind(LCA+暴力)
- POJ 2763Housewife Wind(LCA)
- POJ 2763 Housewife Wind (LCA+线段树)
- LCA+线段树/树状数组 POJ2763 Housewife Wind
- POJ 2763 Housewife Wind
- POJ 2763 Housewife Wind
- Windows下使用VisualSVN Server搭建SVN服务器
- JNI编程指南-第五章 全局引用和本地引用
- mysql索引
- VIM设置搜索字符高亮
- 重定向
- poj 2763 Housewife Wind (LCA转RMQ+树状数组)
- 九度oj 1195
- Associated Objects
- android中final的理解
- C++primer 阅读笔记-模板与泛型编程(函数模板)
- UVA - 12105 Bigger is Better DP
- ASP.NET 防盗链的实现[HttpHandler]
- 数据库空值和null的区别
- 字符串转数字,包括正数,负数,小数