[POJ3237]树的维护 树链剖分+线段树

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 110000
#define inf 0x3fffffff

int n;
int e[N],w[N],ne[N],v[N];

int nn=0;
void add(int x,int y,int z){
    ne[++nn]=e[x],e[x]=nn,v[nn]=y,w[nn]=z;
}
int dp[N],top[N],fa[N],val[N];
int q[N],he,bo;
int we[N],siz[N],num[N],rk[N];
int tot;
struct node{
    int l,r,maxx,e,minn;
}t[N*4];
void down(int x){
    if(t[x].e){
        t[x<<1].e^=1;
        t[(x<<1)+1].e^=1;
        int u=t[x<<1].maxx;
        t[x<<1].maxx=-t[x<<1].minn;
        t[x<<1].minn=-u;
        u=t[(x<<1)+1].maxx;
        t[(x<<1)+1].maxx=-t[(x<<1)+1].minn;
        t[(x<<1)+1].minn=-u;
        t[x].e=0;
    }
}
void build(int l,int r,int k){
    t[k].l=l,t[k].r=r;
    if(l==r){
        t[k].minn=t[k].maxx=val[num[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,k<<1);
    build(mid+1,r,(k<<1)+1);
    t[k].maxx=max(t[k<<1].maxx,t[(k<<1)+1].maxx);
    t[k].minn=min(t[k<<1].minn,t[(k<<1)+1].minn);
}
void rev(int l,int r,int k){
    if(t[k].l>=l&&t[k].r<=r){
        t[k].e^=1;
        int u=t[k].maxx;
        t[k].maxx=-t[k].minn;
        t[k].minn=-u;
        return;
    }
    down(k);
    if(t[k<<1].l<=r&&t[k<<1].r>=l)rev(l,r,k<<1);
    if(t[(k<<1)+1].l<=r&&t[(k<<1)+1].r>=l)rev(l,r,(k<<1)+1);
    t[k].maxx=max(t[k<<1].maxx,t[(k<<1)+1].maxx);
        t[k].minn=min(t[k<<1].minn,t[(k<<1)+1].minn);
}
int ans;
void ask(int l,int r,int k){
    if(t[k].l>=l&&t[k].r<=r){
        ans=max(ans,t[k].maxx);
        return;
    }
        down(k);
    if(t[k<<1].l<=r&&t[k<<1].r>=l)ask(l,r,k<<1);
    if(t[(k<<1)+1].l<=r&&t[(k<<1)+1].r>=l)ask(l,r,(k<<1)+1);
}
void change(int l,int k,int y){
    if(t[k].l==t[k].r){
        t[k].maxx=y;
        t[k].minn=y;
        return;
    }
    down(k);
    if(t[k<<1].r>=l)change(l,k<<1,y);
    else change(l,(k<<1)+1,y);
    t[k].maxx=max(t[k<<1].maxx,t[(k<<1)+1].maxx);
        t[k].minn=min(t[k<<1].minn,t[(k<<1)+1].minn);
}
int ASK(int l,int r){
    ans=-inf;
    ask(l,r,1);
    return ans;
}
void dfs(int x,int ff,int tp){
    num[++tot]=x;
    rk[x]=tot;
    top[x]=tp;
    if(we[x])dfs(we[x],x,tp);
    for(int i=e[x];i;i=ne[i])if(v[i]!=ff&&we[x]!=v[i]){
        dfs(v[i],x,v[i]);
    }
}
int Ask(int x,int y){
    int kk=-inf;
    while(1){
        if(top[x]==top[y]){
            if(x==y)break;
            if(dp[x]<dp[y])swap(x,y);
            kk=max(kk,ASK(rk[y]+1,rk[x]));
            break;
        }
        if(dp[top[x]]>dp[top[y]])swap(x,y);
        kk=max(kk,ASK(rk[top[y]],rk[y]));
        y=fa[top[y]];
    }
    return kk;
}
void REV(int x,int y){
    while(1){
        if(top[x]==top[y]){
            if(x==y)break;
            if(dp[x]<dp[y])swap(x,y);
            rev(rk[y]+1,rk[x],1);
            break;
        }
        if(dp[top[x]]>dp[top[y]])swap(x,y);
        rev(rk[top[y]],rk[y],1);
        y=fa[top[y]];
    }
}
char in[10];
int main(){

    scanf("%d",&n);
     int x,i;
    for(i=1;i<n;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
           add(a,b,c);
           add(b,a,c);
     }
     q[he=bo=1]=1;
     while(he>=bo)for(i=e[x=q[bo++]];i;i=ne[i])if(fa[x]!=v[i])fa[v[i]]=x,q[++he]=v[i],dp[v[i]]=dp[x]+1,val[v[i]]=w[i];
    for(i=he;i>=1;i--){
        siz[q[i]]=1;
        for(int j=e[q[i]];j;j=ne[j])if(fa[q[i]]!=v[j]){
            siz[q[i]]+=siz[v[j]];
            if(!we[q[i]]||siz[v[j]]>siz[we[q[i]]])we[q[i]]=v[j];
        }
    }
    dfs(1,0,1);
    build(1,n,1);
    while(1){
        int a,b;
        scanf("%s",in);
        if(in[0]=='D')break;
        if(in[0]=='N'){
            scanf("%d%d",&a,&b);
            REV(a,b);
        }
        if(in[0]=='C'){
            scanf("%d%d",&a,&b);
            if(dp[v[a<<1]]>dp[v[(a<<1)-1]])a=v[a<<1];
            else a=v[(a<<1)-1];
            change(rk[a],1,b);
        }
        if(in[0]=='Q'){
            scanf("%d%d",&a,&b);
            printf("%d\n",Ask(a,b));
        }
    }
}

 

posted @ 2014-07-04 11:55  wangyucheng  阅读(166)  评论(0编辑  收藏  举报