POJ 2763 Housewife Wind(树链剖分+树状数组)

【题目链接】 http://poj.org/problem?id=2763

【题目大意】

  在一棵树上,给出一些边的边长,有修改边的边长的操作,
  询问每次从当前点到目标点的最短距离

【题解】

  树链剖分之后,相当于树状数组的单点更新和区间查询,
  注意边权转点权之后链操作不覆盖deep最浅的点,这里容易出错

【代码】

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200010;
int tot,x,d[N],num[N],ed=0,u,w,n,m,i,v[N],vis[N],f[N],g[N];
int nxt[N],size[N],son[N],st[N],en[N],dfn,top[N],t;char ch;
void add_edge(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void init(){
    memset(g,dfn=ed=0,sizeof(g));
    memset(v,0,sizeof(v));
    memset(nxt,0,sizeof(nxt));
    memset(son,-1,sizeof(son));
}
void dfs(int x){
    size[x]=1;
    for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
        f[v[i]]=x,d[v[i]]=d[x]+1;
        dfs(v[i]),size[x]+=size[v[i]];
        if(size[v[i]]>size[son[x]])son[x]=v[i];
    }
}
void dfs2(int x,int y){
    if(x==-1)return;
    st[x]=++dfn;top[x]=y;
    if(son[x])dfs2(son[x],y);
    for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
    en[x]=dfn;
}
int c[N];
void add(int x,int val){while(x<=dfn)c[x]+=val,x+=x&-x;}
int query(int x){int s=0;while(x)s+=c[x],x-=x&-x;return s;}
int chain(int x,int y){
    int res=0;
    for(;top[x]!=top[y];x=f[top[x]]){
        if(d[top[x]]<d[top[y]]){int z=x;x=y;y=z;}
        res=res+query(st[x])-query(st[top[x]]-1);
    }if(d[x]<d[y]){int z=x;x=y;y=z;}
    //注意边权转为子节点点权时,链操作不操作deep最浅的点,左端点为开节点
    res=res+query(st[x])-query(st[y]);
    return res;
}
int e[N][3],q,s;
int main(){
    while(~scanf("%d%d%d",&n,&q,&s)){
        init();
        memset(c,0,sizeof(c));
        for(int i=1;i<n;i++){
            scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
            add_edge(e[i][0],e[i][1]);
            add_edge(e[i][1],e[i][0]);
        }dfs(1);dfs2(1,1);
        for(int i=1;i<n;i++){
            if(d[e[i][0]]>d[e[i][1]])swap(e[i][0],e[i][1]);
            add(st[e[i][1]],e[i][2]);
        }int op,x,y;
        while(q--){
            scanf("%d",&op);
            if(op==0){
                scanf("%d",&x);
                printf("%d\n",chain(x,s));
                s=x;
            }else{
                scanf("%d%d",&x,&y);
                add(st[e[x][1]],y-e[x][2]);
                e[x][2]=y;
            }
        }
    }return 0;
}
时间: 2024-08-06 03:46:51

POJ 2763 Housewife Wind(树链剖分+树状数组)的相关文章

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

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

POJ 2763 Housewife Wind LCA转RMQ+时间戳+线段树成段更新

题目来源:POJ 2763 Housewife Wind 题意:给你一棵树 2种操作0 x 求当前点到x的最短路 然后当前的位置为x; 1 i x 将第i条边的权值置为x 思路:树上两点u, v距离为d[u]+d[v]-2*d[LCA(u,v)] 现在d数组是变化的 对应每一条边的变化 他修改的是一个区间 用时间戳处理每个点管辖的区域 然后用线段树修改 线段树的叶子节点村的是根到每一个点的距离 求最近公共祖先没差别 只是堕落用线段树维护d数组 各种错误 4个小时 伤不起 #include <cs

hdu 3966 Aragorn&#39;s Story(树链剖分+树状数组)

题目链接:hdu 3966 Aragorn's Story 题目大意:给定一个棵树,然后三种操作 Q x:查询节点x的值 I x y w:节点x到y这条路径上所有节点的值增加w D x y w:节点x到y这条路径上所有节点的值减少w 解题思路:树链剖分,用树状数组维护每个节点的值. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <cstring>

poj 2763 Housewife Wind(树链剖分+单点查询+区间修改)

题目链接:http://poj.org/problem?id=2763 题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值. 题解:简单的树链剖分. #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int M = 1e5 + 10; struct Edge { int v , next; }edge[M &

POJ 2763 Housewife Wind (树链剖分)

题目地址:POJ 2763 还是树链剖分模板题...不多说.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdio.h>

POJ 2763 Housewife Wind (树链剖分)

题目链接~~> 做题感悟:这题说多了都是泪啊 !明明是一个简单的不能再简单的树链剖分,结果因为一个符号错误找了一下午. 解题思路:   树链剖分 + 线段树插点问线. 代码: #include<iostream> #include<sstream> #include<map> #include<cmath> #include<fstream> #include<queue> #include<vector> #inc

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

题意:在一颗树上,你在s位置,询问s到x的距离,然后移动到x点,第二种操作是修改一条边的权值 思路:直接树链剖分,不知道哪里出的bug,最后发现在主函数询问的时候好像有个标号改着改着改错了 代码: #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=500008; int n,m,s; int a[maxn],sz[maxn],dep[m

POJ 2763 Housewife Wind(DFS序+LCA+树状数组)

Housewife Wind Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 11419   Accepted: 3140 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beauti

(简单) POJ 3321 Apple Tree,树链剖分+树状数组。

Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been carefully nurturing the big apple tree. The tree has N forks which are connected by branches.