fzu2082 过路费(树链剖分)

来源:互联网 发布:动态表情制作软件 编辑:程序博客网 时间:2024/04/29 01:31

边权裸题)

#include <cstdio>#include <algorithm>#include <cstring>using namespace std;#define ll long long#define inf 0x3f3f3f3f#define N 50010inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}int n,m,a[N],p[N],w[N],h[N],dep[N],fa[N],son[N],size[N],top[N],id[N],dfn=0;struct edge{    int to,next,val;}data[N<<1];struct node{    ll sum;}tree[N<<2];void dfs1(int x){    size[x]=1;    for(int i=h[x];i;i=data[i].next){        int y=data[i].to;        if(fa[x]==y) continue;        fa[y]=x;dep[y]=dep[x]+1;p[i>>1]=y;a[y]=data[i].val;        dfs1(y);size[x]+=size[y];        if(size[y]>size[son[x]]) son[x]=y;    }}void dfs2(int x,int tp){    id[x]=++dfn;top[x]=tp;w[dfn]=a[x];    if(son[x]) dfs2(son[x],tp);    for(int i=h[x];i;i=data[i].next){        int y=data[i].to;        if(y==fa[x]||y==son[x]) continue;        dfs2(y,y);    }}inline void pushup(int p){    tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;}void build(int p,int l,int r){    if(l==r){tree[p].sum=w[l];return;}    int mid=l+r>>1;    build(p<<1,l,mid);build(p<<1|1,mid+1,r);    pushup(p);}void change(int p,int l,int r,int x,int val){    if(l==r){tree[p].sum=val;return;}    int mid=l+r>>1;    if(x<=mid) change(p<<1,l,mid,x,val);    else change(p<<1|1,mid+1,r,x,val);    pushup(p);}ll qsum(int p,int l,int r,int x,int y){    if(x<=l&&r<=y) return tree[p].sum;    int mid=l+r>>1;ll res=0;    if(x<=mid) res+=qsum(p<<1,l,mid,x,y);    if(y>mid) res+=qsum(p<<1|1,mid+1,r,x,y);    return res;}ll dosum(int x,int y){    ll res=0;    while(top[x]!=top[y]){        if(dep[top[x]]<dep[top[y]]) swap(x,y);        res+=qsum(1,1,n,id[top[x]],id[x]);        x=fa[top[x]];    }    if(id[x]==id[y]) return res;    if(id[x]>id[y]) swap(x,y);    return res+qsum(1,1,n,id[x]+1,id[y]);}int main(){//  freopen("a.in","r",stdin);while(~scanf("%d%d",&n,&m)){    memset(h,0,sizeof(h));    memset(fa,0,sizeof(fa));    memset(son,0,sizeof(son));dfn=0;    for(int i=1;i<n;++i){        int x=read(),y=read(),v=read();        data[i<<1].to=y;data[i<<1].next=h[x];h[x]=i<<1;data[i<<1].val=v;        data[i<<1|1].to=x;data[i<<1|1].next=h[y];h[y]=i<<1|1;data[i<<1|1].val=v;    }    dep[1]=1;dfs1(1);dfs2(1,1);build(1,1,n);    while(m--){        int op=read(),x=read(),y=read();        if(op==0) change(1,1,n,id[p[x]],y);        else printf("%lld\n",dosum(x,y));    }}    return 0;}
原创粉丝点击