【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板

题目:
树链剖分:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace  std;
#define MAXN 10024
#define MAXLOG 14
#define INF 0x7fffffff
int n,T,size[MAXN+10],dep[MAXN+10],fa[MAXN+10][MAXLOG+1],wt[MAXN+10]={0,-INF},bl[MAXN+10],length[MAXN+10],id2v[MAXN+10];
int tmax[MAXN*4+10],*ttop,*root[MAXN+10],pos[MAXN+10];
bool f;
struct node{
    int v,wt,pos;
    node *next;
}*adj[MAXN+10],edge[MAXN*2+10],*ecnt;
void addedge(int u,int v,int wt,int pos){
    node *p=++ecnt;
    p->v=v;
    p->wt=wt;
    p->pos=pos;
    p->next=adj[u];
    adj[u]=p;
}
void Read(int &x){
    char c;
    while(c=getchar(),c!=EOF)
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            ungetc(c,stdin);
            return;
        }
}
void dfs1(int u,int father){
    fa[u][0]=father;
    dep[u]=dep[father]+1;
    size[u]=1;
    for(int i=1;i<=MAXLOG;i++)
        fa[u][i]=fa[fa[u][i-1]][i-1];
    for(node *p=adj[u];p;p=p->next){
        if(p->v!=father){
            id2v[p->pos]=p->v;
            wt[p->v]=p->wt;
            dfs1(p->v,u);
            size[u]+=size[p->v];
        }
    }
}
inline int *NewTree(int len){
    int *ret=ttop;
    ttop+=len*4;
    return ret;
}
void insert(int *tmax,int i,int l,int r,int pos,int wt){
    if(l==r){
        tmax[i]=wt;
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid)
        insert(tmax,i<<1,l,mid,pos,wt);
    else
        insert(tmax,(i<<1)+1,mid+1,r,pos,wt);
    tmax[i]=max(tmax[i<<1],tmax[(i<<1)+1]);
}
void dfs2(int u,int len,int father){
    int heavy=0,i;
    for(node *p=adj[u];p;p=p->next)
        if(p->v!=father&&size[p->v]>size[heavy])
            heavy=p->v;
    if(!heavy){
        int tp=u;
        for(i=1;i<len;i++)
            tp=fa[tp][0];
        root[tp]=NewTree(len);
        length[tp]=len;
        for(i=len;i;i--){
            bl[u]=tp;
            pos[u]=i;
            insert(root[tp],1,1,len,i,wt[u]);
            u=fa[u][0];
        }
        return;
    }
    dfs2(heavy,len+1,u);
    for(node *p=adj[u];p;p=p->next){
        if(p->v!=father&&p->v!=heavy)
            dfs2(p->v,1,u);
    }
}
void init(){
    Read(n);
    int i,u,v,wt;
    for(i=1;i<n;i++){
        Read(u),Read(v),Read(wt);
        addedge(u,v,wt,i);
        addedge(v,u,wt,i);
    }
    dfs1(1,0);
    dfs2(1,1,0);
}
int LCA(int a,int b){
    if(dep[a]<dep[b])
        swap(a,b);
    int i;
    for(i=MAXLOG;i>=0;i--)
        if(dep[a]-(1<<i)>=dep[b])
            a=fa[a][i];
    if(a==b)
        return a;
    for(i=MAXLOG;i>=0;i--)
        if(fa[a][i]!=fa[b][i])
            a=fa[a][i],b=fa[b][i];
    return fa[a][0];
}
int find(int *tmax,int i,int l,int r,int ll,int rr){
    if(l>=ll&&r<=rr)
        return tmax[i];
    if(l>rr||r<ll)
        return -INF;
    int mid=(l+r)>>1;
    return max(find(tmax,i<<1,l,mid,ll,rr),find(tmax,(i<<1)+1,mid+1,r,ll,rr));
}
int query(int lca,int a){
    int ret=-INF;
    while(lca!=a){
        if(bl[a]!=bl[lca]){
            ret=max(find(root[bl[a]],1,1,length[bl[a]],1,pos[a]),ret);
            a=fa[bl[a]][0];
        }
        else{
            ret=max(find(root[bl[a]],1,1,length[bl[a]],pos[lca]+1,pos[a]),ret);
            break;
        }
    }
    return ret;
}
void solve(){
    char s[10];
    int lca,a,b;
    while(scanf("%s",s),s[0]!='D'){
        Read(a),Read(b);
        if(s[0]=='Q'){
            lca=LCA(a,b);
            printf("%d\n",max(query(lca,a),query(lca,b)));
        }
        else{
            wt[id2v[a]]=b;
            insert(root[bl[id2v[a]]],1,1,length[bl[id2v[a]]],pos[id2v[a]],b);
        }
    }
}
int main()
{
    Read(T);
    while(T--){
        memset(fa,0,sizeof fa);
        memset(adj,0,sizeof adj);
        memset(tmax,0,sizeof tmax);
        ttop=tmax;
        ecnt=edge;
        init();
        solve();
    }
}

动态树(LCT):

#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 10000
using namespace std;
int n,e2id[MAXN+10],T;
void Read(int &x){
    char c;
    while(c=getchar(),c!=EOF)
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            ungetc(c,stdin);
            return;
        }
}
struct node{
    int val,mx,wt;
    node *ch[2],*fa;
    bool pre;
}splay_tree[MAXN+10];
struct nodedge{
    int v,wt,pos;
    nodedge *next;
}edge[MAXN*2+10],*ecnt=edge,*adj[MAXN+10];
inline void addedge(int u,int v,int wt,int pos){
    nodedge *p=++ecnt;
    p->v=v;
    p->wt=wt;
    p->next=adj[u];
    p->pos=pos;
    adj[u]=p;
}
inline void  init(node *p){
    p->ch[0]=p->ch[1]=0;
    p->pre=0;
}
void dfs(int u,int dep,int fa){
    node *x=&splay_tree[u],*y;
    init(x);
    x->val=dep;
    for(nodedge *p=adj[u];p;p=p->next){
        if(p->v!=fa){
            e2id[p->pos]=p->v;
            y=&splay_tree[p->v];
            y->mx=y->wt=p->wt;
            y->fa=x;
            dfs(p->v,dep+1,u);
        }
    }
}
void read(){
    Read(n);
    int u,v,wt,i;
    for(i=1;i<n;i++){
        Read(u),Read(v),Read(wt);
        addedge(u,v,wt,i);
        addedge(v,u,wt,i);
    }
    init(&splay_tree[1]);
    splay_tree[1].fa=0;
    dfs(1,1,0);
}
inline int Get_max(node *p){
    return p?p->mx:0;
}
inline void update(node *p){
    p->mx=max(p->wt,max(Get_max(p->ch[0]),Get_max(p->ch[1])));
}
void Rotate(node *x,int d){
    node *y=x->fa;
    if(y->fa&&y->pre)
        y->fa->ch[y==y->fa->ch[1]]=x;
    x->fa=y->fa;
    if(x->ch[d])
        x->ch[d]->fa=y;
    y->ch[!d]=x->ch[d];
    x->ch[d]=y;
    y->fa=x;
    swap(x->pre,y->pre);
    update(y);
}
void splay(node *x){
    node *y,*z;
    while(x->pre){
        y=x->fa;
        z=y->fa;
        if(!z||!y->pre){
            if(x==y->ch[0])
                Rotate(x,1);
            else
                Rotate(x,0);
        }
        else{
            if(y==z->ch[0])
                if(x==y->ch[0]){
                    Rotate(y,1);
                    Rotate(x,1);
                }
            else{
                Rotate(x,0);
                Rotate(x,1);
            }
            else
                if(x==y->ch[1]){
                    Rotate(y,0);
                    Rotate(x,0);
                }
                else{
                    Rotate(x,1);
                    Rotate(x,0);
                }
        }
    }
    update(x);
}
void access(int a){
    node *x=&splay_tree[a],*y;
    splay(x);
    if(x->ch[1]){
        x->ch[1]->pre=0;
        x->ch[1]=0;
    }
    update(x);
    while(1){
        y=x->fa;
        if(!y)
            return;
        splay(y);
        if(y->ch[1])
            y->ch[1]->pre=0;
        y->ch[1]=x;
        x->pre=1;
        splay(x);
    }
    splay(x);
}
int query(int a){
    node *x=&splay_tree[a],*y;
    int ans;
    splay(x);
    if(!x->fa)
        return Get_max(x->ch[1]);
    if(x->ch[1]){
        x->ch[1]->pre=0;
        x->ch[1]=0;
    }
    update(x);
    while(1){
        y=x->fa;
        splay(y);
        ans=Get_max(y->ch[1]);
        if(y->ch[1])
            y->ch[1]->pre=0;
        y->ch[1]=x;
        x->pre=1;
        if(!y->fa){
            ans=max(ans,Get_max(x));
            splay(x);
            return ans;
        }
        splay(x);
    }
}
void solve(){
    char s[10];
    int a,b;
    while(scanf("%s",s),s[0]!='D')
        if(s[0]=='Q'){
            Read(a),Read(b);
            access(a);
            printf("%d\n",query(b));
        }
        else{
            Read(a),Read(b);
            access(e2id[a]);
            splay_tree[e2id[a]].wt=b;
            update(&splay_tree[e2id[a]]);
        }
}
int main()
{
    Read(T);
    while(T--){
        memset(adj,0,sizeof adj);
        ecnt=edge;
        read();
        solve();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值