题意: 知道了一颗有  n 个节点的树和树上每条边的权值,对应两种操作:

0 x        输出 当前节点到 x节点的最短距离,并移动到 x 节点位置

1 x val   把第 x 条边的权值改为 val

分析: 树上两个节点a,b的距离可以转化为

dis[a] + dis[b] - 2*dis[lca(a,b)]

其中 dis[i] 表示 i 节点到根的距离,

由于每次修改一条边,树中在这条边下方的 dis[] 值全都会受到影响,这样每条边都对应这一段这条边的管辖区,

可以深搜保存遍历该点的时间戳,ll[i] 表示第一次遍历到该点的时间戳, rr[i] 表示回溯到该点时的时间戳,这样每次

修改边 i 的时候就可以对区间 [ ll[i], rr[i] ] 进行成段更新,成段更新的方式可以在 位置 ll[i] 上加一个权值,在位置

rr[i]+1 上减去这个权值,求和时,sum(ll[i]) 即为该点到根的距离。

#include<stdio.h>
#include<string.h>
#include<math.h>
#define clr(x)memset(x,0,sizeof(x))
#define maxn 200005
struct node
{int to,next,w,xu;
}e[1000000];
int tot;
int head[maxn];
void add(int s,int t,int wi,int xu)
{e[tot].xu=xu;e[tot].w=wi;e[tot].to=t;e[tot].next=head[s];head[s]=tot++;
}
int dp[maxn<<1][18];
int x[maxn<<1];
int d[maxn];
int r[maxn];
int v[maxn];
int f[maxn];
int ll[maxn];
int rr[maxn];
int g[maxn];
int n,m;
int min(int i,int j)
{return d[i]<d[j]?i:j;
}
void makermq(int nn)
{int i,j;for(i=0;i<nn;i++)dp[i][0]=i;for(j=1;(1<<j)<=nn;j++)for(i=1;i+(1<<j)-1<nn;i++)dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int rmq(int l,int r)
{int k=(int)(log((r-l+1)*1.0)/log(2.0));return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
int cnt,ti;
void dfs(int u,int deep)
{v[u]=1;x[cnt]=u;d[cnt]=deep;r[u]=cnt++;ll[u]=++ti;int i,k;for(i=head[u];i;i=e[i].next){k=e[i].to;if(!v[k]){g[e[i].xu]=k;dfs(k,deep+1);x[cnt]=u;d[cnt++]=deep;}}rr[u]=ti;
}
int tree[maxn];
int lowbit(int x)
{return (x)&(-x);
}
void update(int pos,int x)
{while(pos<=n){tree[pos]+=x;pos+=lowbit(pos);}
}
int sum(int pos)
{int s=0;while(pos>0){s+=tree[pos];pos-=lowbit(pos);}return s;
}
int edge[maxn];
int val[maxn];
int main()
{int i,st;while(scanf("%d%d%d",&n,&m,&st)!=EOF){int a,b,c;clr(head);  clr(v);clr(f);     clr(tree);tot=1;ti=-1;for(i=1;i<n;i++){scanf("%d%d%d",&a,&b,&c);val[i]=c;edge[i]=c;add(a,b,c,i);add(b,a,c,i);}cnt=0;dfs(1,0);makermq(2*n-1);for(i=1;i<n;i++){update(ll[g[i]],edge[i]);update(rr[g[i]]+1,-edge[i]);}int op;while(m--){scanf("%d",&op);if(op==1){scanf("%d%d",&a,&b);update(ll[g[a]],-val[a]);update(rr[g[a]]+1,val[a]);update(ll[g[a]],b);update(rr[g[a]]+1,-b);val[a]=b;}else{scanf("%d",&a);int lca,d1,d2,d3;if(r[st]<=r[a])lca=x[rmq(r[st],r[a])];else lca=x[rmq(r[a],r[st])];d1=sum(ll[st]);d2=sum(ll[a]);d3=sum(ll[lca]);st=a;printf("%d\n",d1+d2-2*d3);}}}return 0;
}

转载于:https://www.cnblogs.com/dream-wind/archive/2012/10/03/2710719.html

POJ 2763 Housewife Wind【LCA_RMQ+树状数组】相关推荐

  1. poj 1195(二维树状数组)

    解题思路:这是一道很裸的二维树状数组 AC: #include<stdio.h> #include<string.h> #define N 1100 int c[N][N],n ...

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

    q次询问求两个点之间的距离,并且可以随时修改某条边的长度,最短距离可以用lca来求,但是树上维护每一个点到root的距离必须要用dfs序来记录时间戳,在dfs的时候顺便记录每一条边(u,v)对应的v节 ...

  3. POJ 2763 Housewife Wind 笔记

    n 座小屋,构成一棵树.q 条查询,出发点在小屋 s.接着 n-1 行,道路 i 从小屋 ai 到 bi 需要时间 wi .0 类查询:求从当前位置移到小屋 u 所需时间.1 类查询:将通过道路 i ...

  4. POJ - 2763 Housewife Wind

    传送门 第一次遇到这么有意思的题目. 首先介绍一下dfs序. dfs顾名思义 是用dfs遍历一棵树时,各节点出现的顺序.这样可以把一个无序的问题转换为有序的. dfs最大的特点是一个点的子树一定是一段 ...

  5. POJ 3321 Apple Tree【树状数组】

    题目 There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tr ...

  6. poj 2763 Housewife Wind

    LCA 题意:一个无根树,给出主角一开始所在的位置S,然后下面q个操作,操作包括查询和修改操作,对于查询操作就是当前主角的位置到目的点的距离是多少,然后主角去到那里之后就在那里等待,下次查询的时候那里 ...

  7. 树状数组相关应用之二元变量结构体组队问题

    一维数组处理组队问题 此类问题的处理方法一般采用定一议二 POJ-1900:Moofest 思路: 树状数组 分析: 1 题目给定n头牛的听力v[i]. 现在规定两头你i和j如果要进行交流的话那么消耗 ...

  8. Housewife Wind POJ - 2763 倍增LCA+树状数组 或 树链剖分+线段树

    题目 链接:http://poj.org/problem?id=2763 Language:Default Housewife Wind Time Limit: 4000MS   Memory Lim ...

  9. poj 2352 Stars 线段树(先建后查/边建边查)/树状数组三种方法思路详解,带你深入了解线段树难度⭐⭐⭐★

    poj 2352 Stars 目录 poj 2352 Stars 1.树状数组 2.线段树,先建树后查找 3.线段树,边建树边查找 Description Astronomers often exam ...

最新文章

  1. HEX、DEC、OCT和BIN的解释
  2. 使用C#进行Word 2002和Excel 2002编程
  3. 编程实战一通讯录程序
  4. XLNet:广义自回归预训练语言模型 2019 NIPS
  5. I2C通信读写数据过程
  6. SVN: bdb: BDB1538 Program version 5.3 doesn't match environment version 4.7
  7. vs2012中对于entity framework的使用
  8. RF 无法连接到服务器,这可能由于连接的服务不存在,TCP 错误代码 10061
  9. 从韩春雨事件看学术成果的辨别
  10. 如何让新建网站被搜索引擎快速收录
  11. 通过淘宝数据学习爬虫,python scrapy requests与response对象
  12. 基于51单片机的智能花盆测控(温湿度、光照)【仿真资料-126】
  13. Python网络爬虫:PPT素材
  14. 两个构件的重合点_两构件形成移动副,则两构件重合点的相对速度一定沿移动方向。...
  15. java简单的音乐播放器编程_简单实现java音乐播放器
  16. CCPC-Wannafly Comet OJ 夏季欢乐赛(2019)比赛总结
  17. 耳机不分主从是什么意思_不疯魔不成活!红魔TWS蓝牙耳机告诉你什么是“低延怪兽”...
  18. 音频之声道、采样位宽、采样率转换原理及其代码实现
  19. 音速索尼克 怪人_优势演员评论家方法简介:让我们玩刺猬索尼克!
  20. 基于PaaS和SaaS研发的商业云平台实战 - 精华篇

热门文章

  1. python判断数据是否在另一个集合中_python判断一个集合是否包含了另外一个集合中所有项的方法...
  2. html表格的系列代码,HTML系列(八):表格(示例代码)
  3. iscsi:IO操作流程(四)
  4. 使用ajax提交图片,提交已经注入文件的表单给后台上传图片 使用ajaxsubmit
  5. vue element Form-Item prop
  6. Python `__enter__` `__exit__`(with)
  7. TensorFlow tf.keras.losses.CategoricalCrossentropy
  8. opencv-api getPerspectiveTransform
  9. opencv 图像属性
  10. Matplotlib 三维图像 API