fzu 2082 过路费(树链剖分)

来源:互联网 发布:卷皮淘宝客 编辑:程序博客网 时间:2024/04/30 20:40

思路:树链剖分的裸题了


#include<iostream>#include<cstdio>#include<vector>#include<algorithm>#define LL long longusing namespace std;const int maxn = 50000+100;int siz[maxn],fa[maxn],son[maxn],dep[maxn],top[maxn],id[maxn];int tot;int val[maxn];vector<int>e[maxn];int n,m;struct Node{int u,v;    LL val;}nodes[maxn];LL sum[maxn<<2];#define lson i*2,l,m#define rson i*2+1,m+1,rvoid push_up(int i){sum[i] = sum[i*2] + sum[i*2+1];}void build(int i,int l,int r){if(l==r){sum[i]=val[l];return;}int m = (l+r)>>1;build(lson);build(rson);push_up(i);}LL query(int ql,int qr,int i,int l,int r){if(ql <= l && qr>=r)    return sum[i];int m = (l+r)>>1;LL ans = 0;if (ql <= m)ans+=query(ql,qr,lson);if (m<qr)ans+=query(ql,qr,rson);return ans;}void update(int id,int val,int i,int l,int r){if(l==r){sum[i]=val;return;}int m = (l+r)>>1;if(id <=m)update(id,val,lson);elseupdate(id,val,rson);push_up(i);}void dfs1(int u,int f,int d){siz[u]=1;son[u]=0;fa[u]=f;dep[u]=d;for(int i = 0;i<e[u].size();i++){int v = e[u][i];if(v==f)continue;dfs1(v,u,d+1);siz[u]+=siz[v];if(siz[son[u]] < siz[v])son[u]=v;}}void dfs2(int u,int tp){top[u]=tp;id[u]=++tot;if(son[u])dfs2(son[u],tp);for(int i = 0;i<e[u].size();i++){int v= e[u][i];if(v==fa[u] || v == son[u])continue;dfs2(v,v);}}LL Yougth(int u,int v){int tp1 = top[u],tp2 = top[v];LL ans = 0;while(tp1!=tp2){if (dep[tp1] < dep[tp2]){swap(tp1,tp2);swap(u,v);}ans +=query(id[tp1],id[u],1,1,tot);u = fa[tp1];tp1 = top[u];}if(u==v)return ans;if(dep[u] > dep[v])swap(u,v);ans += query(id[son[u]],id[v],1,1,tot);return ans;}int main(){while(scanf("%d%d",&n,&m)!=EOF){for(int i = 0;i<=n;i++)e[i].clear();for(int i = 1;i<n;i++){scanf("%d%d%lld",&nodes[i].u,&nodes[i].v,&nodes[i].val);e[nodes[i].u].push_back(nodes[i].v);e[nodes[i].v].push_back(nodes[i].u);}tot = 0;dfs1(1,0,1);dfs2(1,1);        for(int i = 1;i<n;i++){if (dep[nodes[i].u] < dep[nodes[i].v])swap(nodes[i].u,nodes[i].v);val[id[nodes[i].u]] = nodes[i].val;}build(1,1,tot);while(m--){int op;scanf("%d",&op);if(op==1){int uu,vv;scanf("%d%d",&uu,&vv);                printf("%lld\n",Yougth(uu,vv));}else {int uu;LL v;scanf("%d%lld",&uu,&v);                update(id[nodes[uu].u],v,1,1,tot);}}}}



Description

有n座城市,由n-1条路相连通,使得任意两座城市之间可达。每条路有过路费,要交过路费才能通过。每条路的过路费经常会更新,现问你,当前情况下,从城市a到城市b最少要花多少过路费。

Input

有多组样例,每组样例第一行输入两个正整数n,m(2 <= n<=50000,1<=m <= 50000),接下来n-1行,每行3个正整数a b c,(1 <= a,b <= n , a != b , 1 <= c <= 1000000000).数据保证给的路使得任意两座城市互相可达。接下来输入m行,表示m个操作,操作有两种:一. 0 a b,表示更新第a条路的过路费为b,1 <= a <= n-1 ; 二. 1 a b , 表示询问a到b最少要花多少过路费。

Output

对于每个询问,输出一行,表示最少要花的过路费。

Sample Input

2 31 2 11 1 20 1 21 2 1

Sample Output

12



0 0
原创粉丝点击