樹鏈剖分模板題【spoj 375】【HDU 3966】【POJ 3237】【poj2763】【bzoj2243】

邊權【spoj 375】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 10010;

struct Edge{
    int to,next;
}edge[maxn*2];

int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos;

void init(){
    pos=0;tot=0;
    memset(head,-1,sizeof head);
    memset(son,-1,sizeof son);
}

void addedge(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}


void dfs_1(int u,int pre,int d){
    deep[u]=d;
    fa[u]=pre;
    num[u]=1;
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v!=pre){
            dfs_1(v,u,d+1);
            num[u]+=num[v];
            if(son[u]==-1||num[v]>num[son[u]]){
                son[u]=v;
            }
        }
    }
}

void dfs_2(int u,int sp){
    top[u]=sp;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1)return;
    dfs_2(son[u],sp);
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v!=fa[u]&&v!=son[u]){
            dfs_2(v,v);
        }
    }
}

struct node{
    int l,r;
    int Max;
}ST[maxn<<2];


void build(int i,int l,int r){
    ST[i].l=l;
    ST[i].r=r;
    ST[i].Max=0;
    if(l==r)return;
    int md=(l+r)/2;
    build(i<<1,l,md);
    build((i<<1)|1,md+1,r);
}

void push_up(int i){
    ST[i].Max=max(ST[i<<1].Max,ST[(i<<1)|1].Max);
}

void update(int i,int k,int val){
    if(ST[i].l==ST[i].r){
        ST[i].Max=val;
        return;
    }
    int md=(ST[i].l+ST[i].r)/2;
    if(k<=md)update(i<<1,k,val);
    else update((i<<1)|1,k,val);
    push_up(i);
}

int qry(int i,int l,int r){
    if(ST[i].l == l && ST[i].r == r){
        return ST[i].Max;
    }
    int md=(ST[i].l+ST[i].r)/2;
    if(r<=md)return qry(i<<1,l,r);
    else if(l>md)return qry((i<<1)|1,l,r);
    return max(qry(i<<1,l,md),qry((i<<1)|1,md+1,r));
}

int find(int u,int v){
    int f1=top[u],f2=top[v];
    int tmp=0;
    while(f1!=f2){
        if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
        tmp=max(tmp,qry(1,p[f1],p[u]));
        u=fa[f1];f1=top[u];
    }
    if(u==v)return tmp;
    if(deep[u]>deep[v])swap(u,v);
    return max(tmp,qry(1,p[son[u]],p[v]));
}
int e[maxn][3];
int main(){
    //freopen("in.txt","r",stdin);
    int t,n;
    for(scanf("%d",&t);t--;){
        init();
        scanf("%d",&n);
        for(int i=0;i<n-1;i++){
            scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
            addedge(e[i][0],e[i][1]);
            addedge(e[i][1],e[i][0]);
        }
        dfs_1(1,0,0);
        dfs_2(1,1);
        build(1,0,pos-1);
        for(int i=0;i<n-1;i++){
            if(deep[e[i][0]]>deep[e[i][1]])swap(e[i][0],e[i][1]);
            update(1,p[e[i][1]],e[i][2]);
        }
        char op[110];
        int u,v;
        while(1){
            scanf("%s",op);
            if (op[0]=='D')break;
            scanf("%d%d",&u,&v);
            if(op[0]=='Q')printf("%d\n",find(u,v));
            else update(1,p[e[u-1][1]],v);
        }
    }
}

邊權【poj2763】

#include<cstdio>
#include<cstring>
#include<algorithm>

#define ls (p<<1)
#define rs (p<<1|1)
#define push_up; T[p].sum=T[ls].sum+T[rs].sum;

using namespace std;
typedef long long ll;
const int maxn = 100011;

struct Edge{
    int to,next;
}edge[maxn<<1];

int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos;
int e[maxn][3];

struct node{
    int l,r;
    ll sum;
}T[maxn<<2];

void build(int p,int l,int r){
    T[p].l=l,T[p].r=r;
    T[p].sum=0;
    if(l==r)return;
    int md=(l+r)>>1;
    build(ls,l,md);
    build(rs,md+1,r);
}

void update(int p,int k,int val){
    if(T[p].l==T[p].r){
        T[p].sum=val;
        return;
    }
    int md=(T[p].l+T[p].r)>>1;
    if(k<=md)update(ls,k,val);
    else update(rs,k,val);
    push_up;
}

ll qry(int p,int l,int r){
    //cout<<l<<' '<<r<<endl;
    //cout<<T[p].l<<' '<<md<<' '<<T[p].r<<endl<<endl;;
    if(T[p].l>=l&&T[p].r<=r)return T[p].sum;
    int md=(T[p].l+T[p].r)>>1;
    if(r<=md)return qry(ls,l,r);
    else if(l>md)return qry(rs,l,r);
    return qry(ls,l,md)+qry(rs,md+1,r);
}

void init(){
    pos=0;tot=0;
    memset(head,-1,sizeof head);
    memset(son,-1,sizeof son);
}

void addedge(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}

void dfs_1(int u,int pre,int d){
    fa[u]=pre;
    deep[u]=d;
    num[u]=1;
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(v!=pre){
            dfs_1(v,u,d+1);
            num[u]+=num[v];
            if(son[u]==-1||num[v]>num[son[u]]){
                son[u]=v;
            }
        }
    }
}

void dfs_2(int u,int sp){
    top[u]=sp;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1)return;
    dfs_2(son[u],sp);
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(v!=fa[u]&&v!=son[u]){
            dfs_2(v,v);
        }
    }
}

ll find(int u,int v){
    int f1=top[u],f2=top[v];
    ll tmp=0;
    while(f1!=f2){
        if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
        tmp+=qry(1,p[f1],p[u]);
        u=fa[f1];f1=top[u];
    }
    if(u==v)return tmp;
    if(deep[u]>deep[v])swap(u,v);
    tmp+=qry(1,p[son[u]],p[v]);
    return tmp;
}

int main(){
    init();
    int n,q,cnt,op,i,w;
    scanf("%d%d%d",&n,&q,&cnt);
    for(int i=1;i<=n-1;i++){
        scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
        addedge(e[i][0],e[i][1]);
        addedge(e[i][1],e[i][0]);
    }
    dfs_1(1,0,0);
    dfs_2(1,1);
    build(1,0,pos-1);
    for(int i=1;i<=n-1;i++){
        if(deep[e[i][0]]>deep[e[i][1]])swap(e[i][0],e[i][1]);
        update(1,p[e[i][1]],e[i][2]);
    }
    while(q--){
        scanf("%d%d",&op,&i);
        if(op){
            scanf("%d",&w);
            update(1,p[e[i][1]],w);
        }else{
            printf("%lld\n",find(cnt,i));
            cnt=i;
        }
    }
}

邊權【POJ 3237】

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ls (p<<1)
#define rs ((p<<1)|1)

using namespace std;
typedef long long ll;
const int maxn = 10010;

struct Edge{
    int to,next;
}edge[maxn*2];

int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos;

void init(){
    pos=0;tot=0;
    memset(head,-1,sizeof head);
    memset(son,-1,sizeof son);
}

void addedge(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}

void dfs_1(int u,int pre,int d){
    deep[u]=d;
    fa[u]=pre;
    num[u]=1;
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(v!=pre){
            dfs_1(v,u,d+1);
            num[u]+=num[v];
            if(son[u]==-1||num[son[u]]<num[v]){
                son[u]=v;
            }
        }
    }
}

void dfs_2(int u,int tp){
    top[u]=tp;
    p[u]=++pos;
    fp[p[u]]=u;
    if(-1==son[u])return;
    dfs_2(son[u],tp);
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(v!=son[u]&&v!=fa[u]){
            dfs_2(v,v);
        }
    }
}

struct node{
    int l,r,mx,mi,lazy;
}T[maxn<<2];

void re(int p){
    T[p].lazy^=1;swap(T[p].mx,T[p].mi);
    T[p].mx*=-1;T[p].mi*=-1;
}

void push_down(int p){
    if(T[p].lazy==1)re(ls),re(rs);
    T[p].lazy=0;
}

void push_up(int p){
    T[p].mx=max(T[ls].mx,T[rs].mx);
    T[p].mi=min(T[ls].mi,T[rs].mi);
}

void update(int p,int k,int val){
    if(T[p].l==T[p].r){
        T[p].mx=val;
        T[p].mi=val;
        T[p].lazy=0;
        return;
    }
    push_down(p);
    int md=(T[p].l+T[p].r)>>1;
    if(k<=md)update(ls,k,val);
    else update(rs,k,val);
    push_up(p);
}
void update_2(int p,int l,int r){
    if(T[p].l>=l&&T[p].r<=r){
        re(p);
        return;
    }
    push_down(p);
    int md = (T[p].l+T[p].r)>>1;
    if(l<=md)update_2(ls,l,r);
    if(r>md)update_2(rs,l,r);
    push_up(p);
}

int qry(int p,int l,int r){
    if(T[p].l>=l&&T[p].r<=r){
        return T[p].mx;
    }
    push_down(p);
    int tmp=-1e16;
    int md = (T[p].l+T[p].r)>>1;
    if(l<=md)tmp=max(tmp,qry(ls,l,r));
    if(r>md)tmp=max(tmp,qry(rs,l,r));
    push_up(p);
    return tmp;
}

void build(int p,int l,int r){
    T[p].l=l,T[p].r=r;
    T[p].lazy=0;
    T[p].mx=0,T[p].mi=0;
    if(l==r)return;
    int md=(l+r)>>1;
    if(l<=md)build(ls,l,md);
    if(r>md)build(rs,md+1,r);
}

int find(int u,int v){
    int f1=top[u],f2=top[v];
    int tmp=-1e16;
    while(f1!=f2){
        if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
        tmp=max(tmp,qry(1,p[f1],p[u]));
        u=fa[f1];f1=top[u];
    }
    if(u==v)return tmp;
    if(deep[u]>deep[v])swap(u,v);
    tmp=max(tmp,qry(1,p[son[u]],p[v]));
    return tmp;
}

void cg(int u,int v){
    int f1=top[u],f2=top[v];
    while(f1!=f2){
        if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
        update_2(1,p[f1],p[u]);
        u=fa[f1];f1=top[u];
    }
    if(u==v)return;
    if(deep[u]>deep[v])swap(u,v);
    update_2(1,p[son[u]],p[v]);
}


int e[maxn][3];

int main(){
    int t,n,m;
    for(scanf("%d",&t);t--;){
        init();
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
            addedge(e[i][0],e[i][1]);
            addedge(e[i][1],e[i][0]);
        }
        dfs_1(1,0,0);

        dfs_2(1,1);
        build(1,1,pos);//cout<<23333<<endl;
        for(int i=1;i<=n-1;i++){
            if(deep[e[i][0]]>deep[e[i][1]])swap(e[i][0],e[i][1]);
            update(1,p[e[i][1]],e[i][2]);
        }
        char op[50];
        int u,v;
        while(1){
            scanf("%s",op);
            if(op[0]=='D')break;
            scanf("%d%d",&u,&v);
            if(op[0]=='Q')printf("%d\n",find(u,v));
            if(op[0]=='C')update(1,p[e[u][1]],v);
            if(op[0]=='N')cg(u,v);
        }
    }
    return 0;
}

點權【HDU 3966】

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 50050;

struct Edge{
    ll to,next;
}edge[maxn*2];

ll head[maxn],tot;
ll top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
ll pos;
ll a[maxn];
ll n;
void init(){
    pos=0;tot=0;
    memset(head,-1,(n+5)*sizeof(ll));
    memset(son,-1,(n+5)*sizeof(ll));
}

void addedge(ll u,ll v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}


void dfs_1(ll u,ll pre,ll d){
    deep[u]=d;
    fa[u]=pre;
    num[u]=1;
    for(ll i=head[u];i!=-1;i=edge[i].next){
        ll v=edge[i].to;
        if(v!=pre){
            dfs_1(v,u,d+1);
            num[u]+=num[v];
            if(son[u]==-1||num[v]>num[son[u]]){
                son[u]=v;
            }
        }
    }
}

void dfs_2(ll u,ll sp){
    top[u]=sp;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1)return;
    dfs_2(son[u],sp);
    for(ll i=head[u];i!=-1;i=edge[i].next){
        ll v=edge[i].to;
        if(v!=fa[u]&&v!=son[u]){
            dfs_2(v,v);
        }
    }
}

struct node{
    ll l,r,lazy;
    ll sum;
}ST[maxn<<2];


void build(ll i,ll l,ll r){
    ST[i].l=l;
    ST[i].r=r;
    ST[i].sum=0;
    ST[i].lazy=0;
    if(l==r)return;
    ll md=(l+r)/2;
    build(i<<1,l,md);
    build((i<<1)|1,md+1,r);
}

void push_up(ll i){
    ST[i].sum=ST[i<<1].sum+ST[(i<<1)|1].sum;
}
void push_down(ll i){
    ST[i<<1].lazy+=ST[i].lazy;
    ST[(i<<1)|1].lazy+=ST[i].lazy;
    ST[i<<1].sum+=(ST[i<<1].r-ST[i<<1].l+1)*ST[i].lazy;
    ST[(i<<1)|1].sum+=(ST[(i<<1)|1].r-ST[(i<<1)|1].l+1)*ST[i].lazy;
    ST[i].lazy=0;
}

void update(ll i,ll l,ll r,ll val){
    if(ST[i].l>=l&&ST[i].r<=r){
        ST[i].lazy+=val;
        ST[i].sum+=(ST[i].r-ST[i].l+1)*val;
        return;
    }
    push_down(i);
    ll md=(ST[i].l+ST[i].r)/2;
    if(l<=md)update(i<<1,l,r,val);
    if(r>md) update((i<<1)|1,l,r,val);
    push_up(i);
}

ll qry(ll i,ll l,ll r){
    if(ST[i].l == l && ST[i].r == r){
        return ST[i].sum;
    }
    if(ST[i].lazy){
        push_down(i);
        push_up(i);
    }
    ll md=(ST[i].l+ST[i].r)/2;
    if(r<=md)return qry(i<<1,l,r);
    else if(l>md)return qry((i<<1)|1,l,r);
    return qry(i<<1,l,md)+qry((i<<1)|1,md+1,r);
}

int up(ll u,ll v,ll val){
    int f1=top[u],f2=top[v];
    int tmp=0;
    while(f1!=f2){
        if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
        update(1,p[f1],p[u],val);
        u=fa[f1];f1=top[u];
    }
    if(u==v)update(1,p[u],p[u],val);
    else{
        if(deep[u]>deep[v])swap(u,v);
        update(1,p[u],p[v],val);
    }

}

ll e[maxn][3];
int main(){
    //freopen("in.txt","r",stdin);
    ll t,m,q;
    while(~scanf("%lld%lld%lld",&n,&m,&q)){
        init();
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(ll i=0;i<n-1;i++){
            scanf("%lld%lld",&e[i][0],&e[i][1]);
            addedge(e[i][0],e[i][1]);
            addedge(e[i][1],e[i][0]);
        }
        dfs_1(1,0,0);
        dfs_2(1,1);
        build(1,0,pos-1);
        for(ll i=1;i<=n;i++){
            update(1,p[i],p[i],a[i]);
        }
        char op[110];
        ll u,v,val;
        while(q--){
            scanf("%s",op);
            if (op[0]=='Q'){
                scanf("%lld",&u);
                printf("%lld\n",qry(1,p[u],p[u]));

            }
            else {
                scanf("%lld%lld%lld",&u,&v,&val);
                if(op[0]=='D')val=-val;
                up(u,v,val);
            }
        }
    }
}

點權【bzoj2243】

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ls (p<<1)
#define rs ((p<<1)|1)
using namespace std;
typedef long long ll;
const ll maxn = 100050;

struct Edge{
    ll to,next;
}edge[maxn*2];

int head[maxn],tot;
int top[maxn],fa[maxn],deep[maxn],num[maxn],p[maxn],fp[maxn],son[maxn];
int pos,a[maxn],n,q;
void init(){
    pos=0;tot=0;
    memset(head,-1,(n+5)*sizeof(int));
    memset(son,-1,(n+5)*sizeof(int));
}

void addedge(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}


void dfs_1(int u,int pre,int d){
    deep[u]=d;
    fa[u]=pre;
    num[u]=1;
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(v!=pre){
            dfs_1(v,u,d+1);
            num[u]+=num[v];
            if(son[u]==-1||num[v]>num[son[u]]){
                son[u]=v;
            }
        }
    }
}

void dfs_2(int u,int tp){
    top[u]=tp;
    p[u]=++pos;
    fp[p[u]]=u;
    if(-1==son[u])return;
    dfs_2(son[u],tp);
    for(int i=head[u];~i;i=edge[i].next){
        int v=edge[i].to;
        if(v!=fa[u]&&v!=son[u]){
            dfs_2(v,v);
        }
    }
}

struct node{
    int l,r,lc,rc;
    int num,lazy;
}T[maxn<<2];

void push_up(int p){
    T[p].num=T[ls].num+T[rs].num-(T[ls].rc==T[rs].lc);
    T[p].lc=T[ls].lc;T[p].rc=T[rs].rc;
}

void push_down(int p){
    if(~T[p].lazy){
        T[ls].lc=T[ls].rc=T[ls].lazy=T[p].lazy;
        T[rs].lc=T[rs].rc=T[rs].lazy=T[p].lazy;
        T[ls].num=1;T[rs].num=1;
    }
    T[p].lazy=-1;
}


void build(int p,int l,int r){
    T[p].l=l,T[p].r=r,T[p].lazy=-1;
    if(l==r){
        T[p].lc=T[p].rc=T[p].lazy=a[fp[l]];
        T[p].num=1;
        return;
    }
    int md=(l+r)>>1;
    build(ls,l,md);
    build(rs,md+1,r);
    push_up(p);
}

void update(int p,int l,int r,int val){
    if(T[p].l==l&&T[p].r==r){
        T[p].lc=T[p].rc=T[p].lazy=val;
        T[p].num=1;
        return;
    }
    push_down(p);
    int md=(T[p].l+T[p].r)>>1;
    if(r<=md)update(ls,l,r,val);
    else if(l>md)update(rs,l,r,val);
    else{
        update(ls,l,md,val);
        update(rs,md+1,r,val);
    }
    push_up(p);
}

node qry(int p,int l,int r){
    if(T[p].l==l&&T[p].r==r){
        return T[p];
    }
    node res,tmp;
    push_down(p);
    int md=(T[p].l+T[p].r)>>1;
    if(r<=md)return qry(ls,l,r);
    else if(l>md)return qry(rs,l,r);
    else{
        res=qry(ls,l,md);
        tmp=qry(rs,md+1,r);
        res.num+=tmp.num-(res.rc==tmp.lc);
        res.rc=tmp.rc;
        return res;
    }
}

void cg(int u,int v,int val){
    int f1=top[u],f2=top[v];
    int tmp=0;
    while(f1!=f2){
        if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2);
        update(1,p[f1],p[u],val);
        u=fa[f1];f1=top[u];
    }
    if(u==v)update(1,p[u],p[u],val);
    else{
        if(deep[u]>deep[v])swap(u,v);
        update(1,p[u],p[v],val);
    }
}

//
//    if(deep[u]>deep[v])swap(u,v);
//    tmp=max(tmp,qry(1,p[son[u]],p[v]));
//    return tmp;

int find(int u,int v){
    int f1=top[u],f2=top[v];
    node tmp;
    int res=0,uc=-1,vc=-1;
    while(f1!=f2){
        if(deep[f1]<deep[f2])swap(u,v),swap(f1,f2),swap(uc,vc);
        tmp=qry(1,p[f1],p[u]);
        res+=tmp.num-(uc==tmp.rc);
        uc=tmp.lc;
        u=fa[f1];f1=top[u];
    }
    if(u!=v)if(deep[u]>deep[v])swap(u,v),swap(uc,vc);
        tmp=qry(1,p[u],p[v]);
        res+=tmp.num-(uc==tmp.lc)-(vc==tmp.rc);
        return res;

}


ll e[maxn][3];
int main(){
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&q);
    init();
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<n;i++){
        scanf("%d%d",&e[i][0],&e[i][1]);
        addedge(e[i][0],e[i][1]);
        addedge(e[i][1],e[i][0]);
    }
    dfs_1(1,0,0);
    dfs_2(1,1);
    build(1,1,pos);
    char op[10];
    int u,v,w;
    while(q--){
        scanf("%s%d%d",op,&u,&v);
        //cout<<op<<endl;
        if(op[0]=='Q')printf("%d\n",find(u,v));
        else {
            scanf("%d",&w);
            cg(u,v,w);
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章