树链剖分维护的都是点,而这道题要求的是边。

解决:就把边权下放,变成点权,注意下放后查询u到v的路径时要除去lca的点权,因为lca的点权是其父亲的边权

细节:线段树的加标记与等于标记的维护与下传

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define mid ((l+r)>>1)
int mx[N*4],fl[N*4],eq[N*4],n;
int head[N],to[N<<1],nex[N<<1],w[N<<1],tot=0;
int cnt=0,id[N],dfn[N],val[N],siz[N],dep[N],fa[N],son[N],top[N];
struct node{ int a,b; } e[N<<1];
void add(int a,int b,int c) { to[++tot]=b; nex[tot]=head[a]; head[a]=tot; w[tot]=c; }
void update(int s) { mx[s]=max(mx[s<<1],mx[s<<1|1]); }
void pushdown(int s)//优先处理=标记 
{
    if(eq[s]!=-1){
        fl[s<<1]=fl[s<<1|1]=0;
        mx[s<<1]=mx[s<<1|1]=eq[s<<1]=eq[s<<1|1]=eq[s];
        eq[s]=-1;
    }
    else if(fl[s]){
        fl[s<<1]+=fl[s]; 
        fl[s<<1|1]+=fl[s]; 
        mx[s<<1]+=fl[s];
        mx[s<<1|1]+=fl[s];
        fl[s]=0;
    }
}
void build(int s,int l,int r)
{
    fl[s]=0; eq[s]=-1;
    if(l==r) { mx[s]=dfn[l]; return ; }
    build(s<<1,l,mid); build(s<<1|1,mid+1,r);
    update(s);
}
void modify_point(int s,int l,int r,int pos,int v)
{
    if(l==r) { mx[s]=v; fl[s]=0; eq[s]=v; return ; }//eq=v??
    pushdown(s);
    if(pos<=mid) modify_point(s<<1,l,mid,pos,v); 
    else modify_point(s<<1|1,mid+1,r,pos,v);
    update(s);
}
void modify_add(int s,int l,int r,int L,int R,int v)
{
    if(L<=l&&r<=R) { mx[s]+=v; fl[s]+=v; return ; }
    pushdown(s);
    if(L<=mid) modify_add(s<<1,l,mid,L,R,v);
    if(R>mid)  modify_add(s<<1|1,mid+1,r,L,R,v);
    update(s);
}
void modify_cover(int s,int l,int r,int L,int R,int v)
{
    //printf("%d %d\n",l,r);
    if(L<=l&&r<=R) { mx[s]=eq[s]=v; fl[s]=0; return ; }
    pushdown(s);
    if(L<=mid) modify_cover(s<<1,l,mid,L,R,v);
    if(R>mid)  modify_cover(s<<1|1,mid+1,r,L,R,v);
    update(s);
}
int query(int s,int l,int r,int L,int R)
{
    int ans=0;
    if(L<=l&&r<=R) return mx[s];
    pushdown(s);
    if(L<=mid) ans=max(ans,query(s<<1,l,mid,L,R));
    if(R>mid)  ans=max(ans,query(s<<1|1,mid+1,r,L,R));
    return ans;
}
void dfs1(int u,int f)
{
    siz[u]=1;
    for(int i=head[u];i;i=nex[i]){
        int v=to[i];
        if(v==f) continue;
        fa[v]=u; dep[v]=dep[u]+1; val[v]=w[i];
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[son[u]]<siz[v]) son[u]=v;
    }
}
void dfs2(int u,int tp)
{
    id[u]=++cnt;
    dfn[cnt]=val[u];
    top[u]=tp;
    if(son[u]) dfs2(son[u],tp);
    for(int i=head[u];i;i=nex[i]){
        int v=to[i];
        if(v==fa[u]||v==son[u]) continue;
        dfs2(v,v);
    }
}
void modify1(int i,int ww)
{
    if(fa[e[i].a]==e[i].b) modify_point(1,1,n,id[e[i].a],ww);
    else modify_point(1,1,n,id[e[i].b],ww);
}
void modify2(int a,int b,int ww,bool op)
{
    while(top[a]!=top[b]){
        if(dep[top[a]]<dep[top[b]]) swap(a,b);
        if(op)
        modify_add(1,1,n,id[top[a]],id[a],ww);

        else modify_cover(1,1,n,id[top[a]],id[a],ww);
        a=fa[top[a]]; 
    }
    if(dep[a]<dep[b]) swap(a,b);
    if(op) modify_add(1,1,n,id[b]+1,id[a],ww);//+1是为了保证没有算到lca那一条边!! id[b]+1 
    else modify_cover(1,1,n,id[b]+1,id[a],ww);//要记得+1!! 
}
int query_link(int a,int b)
{
    int ans=0;
    while(top[a]!=top[b]){
        if(dep[top[a]]<dep[top[b]]) swap(a,b);
        ans=max(ans,query(1,1,n,id[top[a]],id[a]));
        a=fa[top[a]];
    }
    if(dep[a]<dep[b]) swap(a,b);
    ans=max(ans,query(1,1,n,id[b]+1,id[a]));//
    return ans;
}
char op[10];
int main()
{
    int a,b,c,x;
    scanf("%d",&n);
    for(int i=1;i<=n-1;++i) 
     scanf("%d%d%d",&e[i].a,&e[i].b,&c),add(e[i].a,e[i].b,c),add(e[i].b,e[i].a,c);
    dfs1(1,0); dfs2(1,1); build(1,1,n);
    while(1){
        scanf("%s",op);
        if(op[0]=='S') break;
        scanf("%d%d",&a,&b);
        if(op[0]=='C'&&op[1]=='h') modify1(a,b);
        else if(op[0]=='C') scanf("%d",&x),modify2(a,b,x,0);
        else if(op[0]=='A') scanf("%d",&x),modify2(a,b,x,1);
        else printf("%d\n",query_link(a,b));
    }
}
/*
10
1 6 0
2 10 8
3 5 8
4 9 1
5 8 3
6 7 1
7 5 0
9 2 8
10 6 0
Cover 5 9 1
Max 7 10
Add 4 2 5
Change 2 6
Add 9 2 8
Change 3 6
Max 1 6  
Cover 2 7 3
Max 7 9
Cover 5 8 5
Stop
ans 1 0 14
*/
View Code

 

posted on 2019-07-25 21:47  rua-rua-rua  阅读(149)  评论(0编辑  收藏  举报