树链剖分模板题汇总

记录几个树链剖分的模板题,包括点操作,边操作和带方向的操作。

点操作

HDU 3966

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 50000+200;

struct sad
{
    int to,next;
}G[maxn<<2];
int h[maxn],si;

void add(int u,int v)
{
    G[si].to=v;
    G[si].next=h[u];
    h[u]=si++;
}

int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d)
{
    fa[u] = f;
    dep[u] = d;
    siz[u] = 1;
    son[u] = -1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if( v != f )
        {
            dfs1(v,u,d+1);
            siz[u] += siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}

int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
    top[u]=sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if( son[u] == -1 ) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next)
    {
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}

int rs[maxn];
void upp(int x,int p)
{
    while(x<=pos)
    {
        rs[x]+=p;
        x+=x&-x;
    }
}
int get(int x)
{
    int ret=0;
    while(x)
    {
        ret += rs[x];
        x-=x&-x;
    }
    return ret;
}

void Change(int u,int v,int d)
{
    int f1=top[u] , f2=top[v];
    while(f1 != f2){
        if( dep[f1] < dep[f2] )
        {
            swap(f1,f2);
            swap(u,v);
        }
        upp(p[f1],d);
        upp(p[u]+1,-d);
        u=fa[f1];
        f1=top[u];
    }
    if( dep[u] > dep[v] ) swap(u,v);
    upp(p[u],d);
    upp(p[v]+1,-d);
}

int A[maxn];

int main()
{
    //freopen("input.txt","r",stdin);
    int n,m,P,u,v,d;
    char c;
    while(~scanf("%d%d%d",&n,&m,&P))
    {
        clr(h,-1);
        si=0;
        clr(rs,0);
        pos=1;
        for(int i=1;i<=n;i++)
            scanf("%d",&A[i]);
        for(int i=0;i<n-1;i++)
        {
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        dfs1(1,-1,1);
        dfs2(1,1);
        for(int i=1;i<=n;i++)
            Change(i,i,A[i]);
        for(int i=0;i<P;i++)
        {
            scanf(" %c",&c);
            if( c == 'Q' )
            {
                scanf("%d",&u);
                printf("%d\n",get(p[u]));
            }else{
                scanf("%d%d%d",&u,&v,&d);
                if( c == 'D' ) d*=-1;
                Change(u,v,d);
            }
        }
    }
    return 0;
}

HYSBZ 1036

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 30000 + 30;

struct edge{
    int to,next;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v){
    G[si].to=v;
    G[si].next=h[u];
    h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d){
    fa[u]=f;
    dep[u]=d;
    siz[u]=1;
    son[u]=-1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(v^f){
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf){
    top[u]=sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}
int w[maxn];
int rs[maxn<<2],rm[maxn<<2];
void pushup(int rt){
    rs[rt] = rs[rt<<1] + rs[rt<<1|1];
    rm[rt] = max(rm[rt<<1],rm[rt<<1|1]);
}
void build(int l,int r,int rt){
    if(l==r){
        rs[rt] = rm[rt] = w[fp[l]];
        return ;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
void update(int pos,int v,int l,int r,int rt){
    if(l==r){
        rs[rt] = rm[rt] = v;
        return ;
    }
    int m=l+r>>1;
    if( pos <= m ) update(pos,v,lson);
    else update(pos,v,rson);
    pushup(rt);
}
int qs,qm;
void query(int L,int R,int l,int r,int rt){
    if(L<=l&&r<=R){
        qs += rs[rt];
        qm = max(qm,rm[rt]);
        return ;
    }
    int m=l+r>>1;
    if( L <= m ) query(L,R,lson);
    if( m < R ) query(L,R,rson);
}

void Query(int u,int v){
    int f1=top[u],f2=top[v];
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        query(p[f1],p[u],1,pos-1,1);
        u=fa[f1];
        f1=top[u];
    }
    if( dep[u] > dep[v] ) swap(u,v);
    query(p[u],p[v],1,pos-1,1);
}
void init()
{
    clr(h,-1);
    si=0;
    pos=1;
}

char s[200];

int main()
{
    //freopen("input.txt","r",stdin);
    int n;
    while(~scanf("%d",&n)){
        init();
        int u,v;
        for(int i=0;i<n-1;i++){
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]);
        dfs1(1,-1,1);
        dfs2(1,1);
        build(1,pos-1,1);
        int q;
        scanf("%d",&q);
        for(int i=0;i<q;i++){
            scanf("%s%d%d",s,&u,&v);
            if(!strcmp(s,"CHANGE"))
                update(p[u],v,1,pos-1,1);
            else if(!strcmp(s,"QMAX"))
            {
                qm = -inf;
                Query(u,v);
                printf("%d\n",qm);
            }else{
                qs=0;
                Query(u,v);
                printf("%d\n",qs);
            }
        }
    }
    return 0;
}

LightOJ 1348

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 30000+300;
struct edge{
    int to,next;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v){
    G[si].to=v;
    G[si].next=h[u];
    h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d){
    fa[u]=f;
    dep[u]=d;
    siz[u]=1;
    son[u]=-1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(v^f){
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf){
    top[u]=sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}

int rs[maxn];
void upp(int x,int p){
    while(x<=pos){
        rs[x]+=p;
        x+=x&-x;
    }
}
int get(int x){
    int ret=0;
    while(x){
        ret += rs[x];
        x-=x&-x;
    }
    return ret;
}

int Query(int u,int v){
    int tmp=0;
    int f1=top[u],f2=top[v];
    while(f1^f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        tmp += get(p[u]) - get(p[f1]-1);
        u=fa[f1];
        f1=top[u];
    }
    if( dep[u] > dep[v] ) swap(u,v);
    tmp += get(p[v]) - get(p[u]-1);
    return tmp;
}

void init()
{
    clr(h,-1);
    si=0;
    pos=1;
}

int w[maxn];

int main()
{
//  freopen("input.txt","r",stdin);
    int T,CASE=0;
    scanf("%d",&T);
    while(T--){
        init();
        clr(rs,0);
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&w[i]);
        int a,b;
        for(int i=0;i<n-1;i++)
        {
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        dfs1(0,-1,1);
        dfs2(0,0);
        for(int i=0;i<n;i++)
            upp(p[i],w[i]);
        int q,c;
        scanf("%d",&q);
        printf("Case %d:\n",++CASE);
        for(int i=0;i<q;i++){
            scanf("%d%d%d",&c,&a,&b);
            if( c == 0 )
                printf("%d\n",Query(a,b));
            else
            {
                upp(p[a],b-w[a]);
                w[a]=b;
            }
        }
    }
    return 0;
}

边操作

SPOJ QTREE

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 10000+20;

struct sad
{
    int to,next,id;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v,int id){
    G[si].to=v;
    G[si].id=id;
    G[si].next=h[u];
    h[u]=si++;
}

int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
int fid[maxn];
void dfs1(int u,int f,int d)
{
    fa[u]=f;
    dep[u]=d;
    siz[u]=1;
    son[u]=-1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(v^f){
            fid[G[i].id]=v;
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
    top[u]=sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}

int col[maxn<<2],ma[maxn<<2],mi[maxn<<2];
void pushdown(int rt)
{
    if(col[rt])
    {
        col[rt<<1] ^= 1;
        col[rt<<1|1] ^= 1;

        swap(ma[rt<<1],mi[rt<<1]);
        ma[rt<<1]*=-1;
        mi[rt<<1]*=-1;

        swap(ma[rt<<1|1],mi[rt<<1|1]);
        ma[rt<<1|1]*=-1;
        mi[rt<<1|1]*=-1;

        col[rt]=0;
    }
}
void pushup(int rt)
{
    ma[rt] = max(ma[rt<<1],ma[rt<<1|1]);
    mi[rt] = min(mi[rt<<1],mi[rt<<1|1]);
}
void build(int l,int r,int rt)
{
    col[rt]=0;
    if(l==r)
    {
        ma[rt]=mi[rt]=0;
        return ;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
void update(int pos,int v,int l,int r,int rt)
{
    if(l==r)
    {
        ma[rt]=mi[rt]=v;
        return ;
    }
    pushdown(rt);
    int m=l+r>>1;
    if( pos <= m ) update(pos,v,lson);
    else update(pos,v,rson);
    pushup(rt);
}
void update2(int L,int R,int l,int r,int rt)
{
    if( L <= l && r <= R )
    {
        swap(ma[rt],mi[rt]);
        ma[rt]*=-1;
        mi[rt]*=-1;
        col[rt] ^= 1;
        return ;
    }
    pushdown(rt);
    int m=l+r>>1;
    if( L <= m ) update2(L,R,lson);
    if( m < R ) update2(L,R,rson);
    pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if( L <= l && r <= R )
        return ma[rt];
    int ret=-inf;
    int m=l+r>>1;
    pushdown(rt);
    if( L <= m ) ret = max(ret,query(L,R,lson));
    if( m < R ) ret = max(ret,query(L,R,rson));
    return ret;
}
void Change(int u,int v)
{
    int f1=top[u],f2=top[v];
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        update2(p[f1],p[u],1,pos-1,1);
        u=fa[f1];
        f1=top[u];
    }
    if(u==v) return ;
    if(dep[u]>dep[v]) swap(u,v);
    update2(p[son[u]],p[v],1,pos-1,1);
}
int Query(int u,int v){
    int ret=-inf;
    int f1=top[u],f2=top[v];
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        ret = max(ret,query(p[f1],p[u],1,pos-1,1));
        u=fa[f1];
        f1=top[u];
    }
    if(u==v) return ret;
    if(dep[u]>dep[v]) swap(u,v);
    ret = max(ret,query(p[son[u]],p[v],1,pos-1,1));
    return ret;
}

void init(){
    clr(h,-1);
    si=0;
    pos=1;
}

int w[maxn];
char s[100];

int main()
{
//  freopen("input.txt","r",stdin);
    int T,n;
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d",&n);
        int a,b;
        for(int i=1;i<=n-1;i++){
            scanf("%d%d%d",&a,&b,&w[i]);
            add(a,b,i);
            add(b,a,i);
        }
        dfs1(1,-1,1);
        dfs2(1,1);
        build(1,pos-1,1);
        for(int i=1;i<=n-1;i++)
            update(p[fid[i]],w[i],1,pos-1,1);
        while(~scanf("%s",s))
        {
            if(!strcmp(s,"QUERY"))
            {
                scanf("%d%d",&a,&b);
                printf("%d\n",Query(a,b));
            }else if(!strcmp(s,"NEGATE"))
            {
                scanf("%d%d",&a,&b);
                Change(a,b);
            }else if(!strcmp(s,"CHANGE"))
            {
                scanf("%d%d",&a,&b);
                update(p[fid[a]],b,1,pos-1,1);
            }else
                break;
        }
    }
    return 0;
}

POJ 2763

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 100001+20;

struct sad{
    int to,next,id;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v,int id)
{
    G[si].to=v;
    G[si].id=id;
    G[si].next=h[u];
    h[u]=si++;
}

int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
int fid[maxn];
void dfs1(int u,int f,int d)
{
//  debug(u);
    fa[u]=f;
    dep[u]=d;
    siz[u]=1;
    son[u]=-1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
//      debug(v);
        if(v!=f){
            fid[G[i].id]=v;
            dfs1(v,u,d+1);
            siz[u] += siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
    top[u]=sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next)
    {
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}

int rs[maxn];
void upp(int x,int p)
{
    while(x<=pos)
    {
        rs[x]+=p;
        x+=x&-x;
    }
}
int get(int x)
{
    int ret=0;
    while(x)
    {
        ret += rs[x];
        x-=x&-x;
    }
    return ret;
}

int Query(int u,int v)
{
    int ret=0,f1=top[u],f2=top[v];
    while(f1!=f2)
    {
        if(dep[f1]<dep[f2])
        {
            swap(f1,f2);
            swap(u,v);
        }
        ret += get(p[u]) - get(p[f1]-1);
        u=fa[f1];
        f1=top[u];
    }
    if(u==v) return ret;
    if(dep[u]>dep[v]) swap(u,v);
    ret += get(p[v]) - get(p[son[u]]-1);
    return ret;
}

void init()
{
    clr(h,-1);
    si=0;
    pos=1;
}

int w[maxn];

int main()
{
//  freopen("input.txt","r",stdin);
    int n,q,s,u,v;
    while(~scanf("%d%d%d",&n,&q,&s))
    {
        init();
        clr(rs,0);
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d%d",&u,&v,&w[i]);
            add(u,v,i);
            add(v,u,i);
        }
        dfs1(1,-1,1);
        dfs2(1,1);
        for(int i=1;i<=n-1;i++)
            upp(p[fid[i]],w[i]);
        int c;
        for(int i=0;i<q;i++)
        {
            scanf("%d",&c);
            if(c==0)
            {
                scanf("%d",&u);
                printf("%d\n",Query(s,u));
                s=u;
            }else{
                int a,b;
                scanf("%d%d",&a,&b);
                upp(p[fid[a]],b-w[a]);
                w[a]=b;
            }
        }
    }
    return 0;
}

POJ 3237

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 10000+20;

struct sad
{
    int to,next,id;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v,int id){
    G[si].to=v;
    G[si].id=id;
    G[si].next=h[u];
    h[u]=si++;
}

int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
int fid[maxn];
void dfs1(int u,int f,int d)
{
    fa[u]=f;
    dep[u]=d;
    siz[u]=1;
    son[u]=-1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(v^f){
            fid[G[i].id]=v;
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf)
{
    top[u]=sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}

int col[maxn<<2],ma[maxn<<2],mi[maxn<<2];
void pushdown(int rt)
{
    if(col[rt])
    {
        col[rt<<1] ^= 1;
        col[rt<<1|1] ^= 1;

        swap(ma[rt<<1],mi[rt<<1]);
        ma[rt<<1]*=-1;
        mi[rt<<1]*=-1;

        swap(ma[rt<<1|1],mi[rt<<1|1]);
        ma[rt<<1|1]*=-1;
        mi[rt<<1|1]*=-1;

        col[rt]=0;
    }
}
void pushup(int rt)
{
    ma[rt] = max(ma[rt<<1],ma[rt<<1|1]);
    mi[rt] = min(mi[rt<<1],mi[rt<<1|1]);
}
void build(int l,int r,int rt)
{
    col[rt]=0;
    if(l==r)
    {
        ma[rt]=mi[rt]=0;
        return ;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
void update(int pos,int v,int l,int r,int rt)
{
    if(l==r)
    {
        ma[rt]=mi[rt]=v;
        return ;
    }
    pushdown(rt);
    int m=l+r>>1;
    if( pos <= m ) update(pos,v,lson);
    else update(pos,v,rson);
    pushup(rt);
}
void update2(int L,int R,int l,int r,int rt)
{
    if( L <= l && r <= R )
    {
        swap(ma[rt],mi[rt]);
        ma[rt]*=-1;
        mi[rt]*=-1;
        col[rt] ^= 1;
        return ;
    }
    pushdown(rt);
    int m=l+r>>1;
    if( L <= m ) update2(L,R,lson);
    if( m < R ) update2(L,R,rson);
    pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
    if( L <= l && r <= R )
        return ma[rt];
    int ret=-inf;
    int m=l+r>>1;
    pushdown(rt);
    if( L <= m ) ret = max(ret,query(L,R,lson));
    if( m < R ) ret = max(ret,query(L,R,rson));
    return ret;
}
void Change(int u,int v)
{
    int f1=top[u],f2=top[v];
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        update2(p[f1],p[u],1,pos-1,1);
        u=fa[f1];
        f1=top[u];
    }
    if(u==v) return ;
    if(dep[u]>dep[v]) swap(u,v);
    update2(p[son[u]],p[v],1,pos-1,1);
}
int Query(int u,int v){
    int ret=-inf;
    int f1=top[u],f2=top[v];
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        ret = max(ret,query(p[f1],p[u],1,pos-1,1));
        u=fa[f1];
        f1=top[u];
    }
    if(u==v) return ret;
    if(dep[u]>dep[v]) swap(u,v);
    ret = max(ret,query(p[son[u]],p[v],1,pos-1,1));
    return ret;
}

void init(){
    clr(h,-1);
    si=0;
    pos=1;
}

int w[maxn];
char s[100];

int main()
{
//  freopen("input.txt","r",stdin);
    int T,n;
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d",&n);
        int a,b;
        for(int i=1;i<=n-1;i++){
            scanf("%d%d%d",&a,&b,&w[i]);
            add(a,b,i);
            add(b,a,i);
        }
        dfs1(1,-1,1);
        dfs2(1,1);
        build(1,pos-1,1);
        for(int i=1;i<=n-1;i++)
            update(p[fid[i]],w[i],1,pos-1,1);
        while(~scanf("%s",s))
        {
            if(!strcmp(s,"QUERY"))
            {
                scanf("%d%d",&a,&b);
                printf("%d\n",Query(a,b));
            }else if(!strcmp(s,"NEGATE"))
            {
                scanf("%d%d",&a,&b);
                Change(a,b);
            }else if(!strcmp(s,"CHANGE"))
            {
                scanf("%d%d",&a,&b);
                update(p[fid[a]],b,1,pos-1,1);
            }else
                break;
        }
    }
    return 0;
}

FZU 2082

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)
const int maxn = 50000+30;
struct edge{
    int to,next,id;
}G[maxn<<1];
int h[maxn],si;
void add(int u,int v,int id){
    G[si].to=v;
    G[si].id=id;
    G[si].next=h[u];
    h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
int fid[maxn];
void dfs1(int u,int f,int d){
    fa[u]=f;
    dep[u]=d;
    siz[u]=1;
    son[u]=-1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(v^f){
            fid[G[i].id]=v;
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf){
    top[u] = sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}
ll rs[maxn];
void upp(int x,ll p){
    while(x<=pos)
    {
        rs[x]+=p;
        x+=x&-x;
    }
}
ll get(int x){
    ll ret=0;
    while(x)
    {
        ret+=rs[x];
        x-=x&-x;
    }
    return ret;
}
ll Query(int u,int v){
    ll ret=0;
    int f1=top[u],f2=top[v];
    while(f1^f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        ret += get(p[u]) - get(p[f1]-1);
        u=fa[f1];
        f1=top[u];
    }
    if(u==v) return ret;
    if( dep[u] > dep[v] ) swap(u,v);
    ret += get(p[v]) - get(p[son[u]]-1);
    return ret;
}
void init(){
    clr(h,-1);
    si=0;
    pos=1;
}
int w[maxn];

int main()
{
//  freopen("input.txt","r",stdin);
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        init();
        clr(rs,0);
        int a,b;
        for(int i=1;i<=n-1;i++){
            scanf("%d%d%d",&a,&b,&w[i]);
            add(a,b,i);
            add(b,a,i);
        }
        dfs1(1,-1,1);
        dfs2(1,1);
        for(int i=1;i<=n-1;i++)
            upp(p[fid[i]],w[i]);
        int c;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&c,&a,&b);
            if( c == 0 )
            {
                upp(p[fid[a]],b-w[a]);
                w[a]=b;
            }else
                printf("%I64d\n",Query(a,b));
        }
    }
    return 0;
}

带方向的操作

HYSBZ 2243

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <queue>
//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
#include <bitset>
//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++) { cout << #a"[" << i << "] = " << (a)[i] << endl; }
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define FOR(i,a,b) \
    for(i=a;a<b?i<=b:i>=b;a<b?i++:i--)

const int maxn = 100000+20;
struct edge{
    int to,next;
}G[maxn<<2];
int h[maxn],si;
void add(int u,int v){
    G[si].to=v;
    G[si].next=h[u];
    h[u]=si++;
}
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d){
    fa[u]=f;
    dep[u]=d;
    siz[u]=1;
    son[u]=-1;
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(v^f){
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[son[u]]<siz[v])
                son[u]=v;
        }
    }
}
int p[maxn],fp[maxn],pos;
void dfs2(int u,int sf){
    top[u]=sf;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    dfs2(son[u],sf);
    for(int i=h[u];~i;i=G[i].next){
        int v=G[i].to;
        if(son[u]!=v&&fa[u]!=v)
            dfs2(v,v);
    }
}

struct sad{
    int s,lc,rc;
    sad(){s=-1;}
    sad(int c)
    {
        s=1;
        lc=rc=c;
    }
    sad operator+(sad b)
    {
        if( s == -1 ) return b;
        if( b.s == -1 ) return *this;
        sad c;
        c.s = s + b.s + ((rc==b.lc)?-1:0);
        c.lc = lc;
        c.rc = b.rc;
        return c;
    }
    sad rev()
    {
        sad c=*this;
        swap(c.lc,c.rc);
        return c;
    }
    void print()
    {
        printf("s %d lc %d rc %d\n",s,lc,rc);
    }
}rs[maxn<<2];

int col[maxn<<2];
void pushup(int rt)
{
    rs[rt] = rs[rt<<1] + rs[rt<<1|1];
}
void pushdown(int rt)
{
    if(col[rt]!=-1){
        rs[rt<<1] = sad(col[rt]);
        rs[rt<<1|1] = sad(col[rt]);
        col[rt<<1] = col[rt<<1|1] = col[rt];
        col[rt] = -1;
    }
}
void build(int l,int r,int rt){
    col[rt]=-1;
    if(l==r)
    {
        rs[rt]=sad(0);
        return ;
    }
    int m=l+r>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if( L <= l && r <= R )
    {
        rs[rt] = sad(col[rt]=c);
        return ;
    }
    pushdown(rt);
    int m=l+r>>1;
    if( L <= m ) update(L,R,c,lson);
    if( m < R ) update(L,R,c,rson);
    pushup(rt);
}
sad query(int L,int R,int l,int r,int rt){
    if( L <= l && r <= R )
        return rs[rt];
    pushdown(rt);
    int m=l+r>>1;
    sad ret;
    if( L <= m ) ret = ret + query(L,R,lson);
    if( m < R ) ret = ret + query(L,R,rson);
    return ret;
}

void Change(int u,int v,int c){
    int f1=top[u],f2=top[v];
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        update(p[f1],p[u],c,1,pos-1,1);
        u=fa[f1];
        f1=top[u];
    }
    if(dep[u]>dep[v]) swap(u,v);
    update(p[u],p[v],c,1,pos-1,1);
}

int Query(int u,int v)
{
    int f1=top[u],f2=top[v];
    sad ans1,ans2;
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
            swap(ans1,ans2);
        }
//      printf("%d->%d ",f1,u);
        ans1 = query(p[f1],p[u],1,pos-1,1) + ans1;
//      ans1.print();
        u=fa[f1];
        f1=top[u];
    }
    if(dep[u]>dep[v])
    {
        swap(u,v);
        swap(ans1,ans2);
    }
    //printf("%d->%d\n",v,u);
    ans2 = query(p[u],p[v],1,pos-1,1) + ans2;
    /*ans2.print();
    ans1.print();
    ans1.rev().print();
    (ans1.rev()+ans2).print();*/
    return (ans1.rev()+ans2).s;
}

void init()
{
    clr(h,-1);
    si=0;
    pos=1;
}

int w[maxn];

int main()
{
    //freopen("input.txt","r",stdin);
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        init();
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]);
        int a,b;
        char c;
        for(int i=0;i<n-1;i++){
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        dfs1(1,-1,1);
        dfs2(1,1);
        build(1,pos-1,1);
        /*for(int i=1;i<=n;i++)
            printf("%d top %d\n",i,top[i]);*/
        for(int i=1;i<=n;i++)
            update(p[i],p[i],w[i],1,pos-1,1);
        for(int i=0;i<m;i++){
            scanf(" %c",&c);
            if( c == 'Q' )
            {
                scanf("%d%d",&a,&b);
                printf("%d\n",Query(a,b));
            }else{
                int v;
                scanf("%d%d%d",&a,&b,&v);
                Change(a,b,v);
            }
        }
    }
    return 0;
}
#include <cstdio> #include <iostream> #include <vector> #define N 30003 #define INF 2147483647 using namespace std; int n,f[N][20],dep[N],siz[N],son[N],top[N],tot,pos[N],w[N]; int Max[N*4],Sum[N*4]; vector <int> to[N]; void dfs1(int x){ siz[x]=1; int sz=to[x].size(); for(int i=0;i<sz;++i){ int y=to[x][i]; if(y==f[x][0])continue; f[y][0]=x; dep[y]=dep[x]+1; dfs1(y); siz[x]+=siz[y]; if(siz[y]>siz[son[x]])son[x]=y; } } void dfs2(int x,int root){ top[x]=root; pos[x]=++tot; if(son[x])dfs2(son[x],root); int sz=to[x].size(); for(int i=0;i<sz;++i){ int y=to[x][i]; if(y==f[x][0] || y==son[x])continue; dfs2(y,y); } } void update(int k,int l,int r,int P,int V){ if(l==r){ Max[k]=Sum[k]=V; return; } int mid=(l+r)>>1; if(P<=mid)update(k*2,l,mid,P,V); else update(k*2+1,mid+1,r,P,V); Max[k]=max(Max[k*2],Max[k*2+1]); Sum[k]=Sum[k*2]+Sum[k*2+1]; } void up(int &x,int goal){ for(int i=15;i>=0;--i) if(dep[f[x][i]]>=goal)x=f[x][i]; } int lca(int x,int y){ if(dep[x]>dep[y])up(x,dep[y]); if(dep[x]<dep[y])up(y,dep[x]); if(x==y)return x; for(int i=15;i>=0;--i) if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i]; return f[x][0]; } int getm(int k,int l,int r,int L,int R){ if(L<=l && r<=R)return Max[k]; int res=-INF,mid=(l+r)>>1; if(L<=mid)res=max(res,getm(k*2,l,mid,L,R)); if(R>mid)res=max(res,getm(k*2+1,mid+1,r,L,R)); return res; } int gets(int k,int l,int r,int L,int R){ if(L<=l && r<=R)return Sum[k]; int res=0,mid=(l+r)>>1; if(L<=mid)res+=gets(k*2,l,mid,L,R); if(R>mid)res+=gets(k*2+1,mid+1,r,L,R); return res; } int main(){ scanf("%d",&n); for(int i=1,a,b;i<n;++i){ scanf("%d%d",&a,&b); to[a].push_back(b); to[b].push_back(a); } dep[1]=1; dfs1(1); dfs2(1,1); for(int i=1;i<=15;++i) for(int j=1;j<=n;++j)f[j][i]=f[f[j][i-1]][i-1]; for(int i=1;i<=n;++i){ scanf("%d",&w[i]); update(1,1,n,pos[i],w[i]); } int q; scanf("%d",&q); while(q--){ char s[10]; int u,v,t; scanf("%s",s); if(s[1]=='H'){ scanf("%d%d",&u,&t); w[u]=t; update(1,1,n,pos[u],t); } if(s[1]=='M'){ scanf("%d%d",&u,&v); int ans=-INF,t=lca(u,v); for(int i=u;i;i=f[top[i]][0]) if(dep[t]<dep[top[i]]) ans=max(ans,getm(1,1,n,pos[top[i]],pos[i])); else{ ans=max(ans,getm(1,1,n,pos[t],pos[i])); break; } for(int i=v;i;i=f[top[i]][0]) if(dep[t]<dep[top[i]]) ans=max(ans,getm(1,1,n,pos[top[i]],pos[i])); else{ ans=max(ans,getm(1,1,n,pos[t],pos[i])); break; } printf("%d\n",ans); } if(s[1]=='S'){ scanf("%d%d",&u,&v); int ans=0,t=lca(u,v); for(int i=u;i;i=f[top[i]][0]) if(dep[t]<dep[top[i]]) ans+=gets(1,1,n,pos[top[i]],pos[i]); else{ ans+=gets(1,1,n,pos[t],pos[i]); break; } for(int i=v;i;i=f[top[i]][0]) if(dep[t]<dep[top[i]]) ans+=gets(1,1,n,pos[top[i]],pos[i]); else{ ans+=gets(1,1,n,pos[t],pos[i]); break; } printf("%d\n",ans-w[t]); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值