zoukankan      html  css  js  c++  java
  • HDU 4836 The Query on the Tree lca || 欧拉序列 || 动态树

    lca的做法还是非常明显的。简单粗暴。

    只是不是正解,假设树是长链就会跪。直接变成O(n)、、

    最后跑的也挺快,出题人还是挺阳光的。。


    动态树的解法也是听别人说能ac的,预计就是放在splay上剖分一下,做法还是比較复杂的。,,

    来一发lca:

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <sstream>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
    #include <string>
    #include <time.h>
    #include <math.h>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-8
    #define pi acos(-1.0)
    typedef long long ll;
    const int maxn=20010;
    int head[maxn],tol,dp[maxn],fa[maxn][20],dep[maxn],weight[maxn];
    struct Edge{
        int next,to;
        Edge(int _next=0,int _to=0){
            next=_next;to=_to;
        }
    }edge[10*maxn];
    void addedge(int u,int v){
        edge[tol]=Edge(head[u],v);
        head[u]=tol++;
    }
    void bfs(int s){
        queue<int> q;
        dep[s]=0,fa[s][0]=s;
        q.push(s);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=1;i<20;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
            for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(v==fa[u][0])continue;
                fa[v][0]=u;
                dep[v]=dep[u]+1;
                q.push(v);
            }
        }
    }
    int LCA(int x,int y){
        if(dep[x]<dep[y])swap(x,y);
        for(int i=19;i>=0;i--)if((1<<i)&(dep[x]-dep[y]))x=fa[x][i];
        if(x==y)return x;
        for(int i=19;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    void dfs(int u,int pre){
        dp[u]=weight[u];
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(v==pre)continue;
            dfs(v,u);
            dp[u]+=dp[v];
        }
    }
    int move(int x,int d){
        for(int i=19;i>=0;i--)
            if(d&(1<<i))x=fa[x][i];
        return x;
    }
    int main()
    {
         int T;
         cin>>T;
         for(int t=1;t<=T;t++){
             int n;
             scanf("%d",&n);
             memset(head,-1,sizeof(head));tol=0;
             for(int i=1;i<n;i++){
                 int x,y;
                 scanf("%d%d",&x,&y);
                 addedge(x,y);
                 addedge(y,x);
             }
             bfs(1);
             for(int i=1;i<=n;i++)scanf("%d",&weight[i]);
             dfs(1,-1);
             printf("Case #%d:
    ",t);
             int Q;
             scanf("%d",&Q);
             int root=1;
             while(Q--){
                 char op[10];
                 int x,y;
                 scanf("%s",op);
                 if(op[0]=='R'){
                     scanf("%d",&x);
                     root=x;
                 }
                 else if(op[0]=='C'){
                     scanf("%d%d",&x,&y);
                     int dd=x;
                     while(1){
                         dp[dd]+=y-weight[x];
                         if(dd==1)break;
                         dd=fa[dd][0];
                     }
    weight[x] = y;
                 }
                 else {
                     scanf("%d",&x);
                     if(x==root)printf("%d
    ",dp[1]);
                     else {
                         int lca=LCA(x,root);
                         if(lca==x){
                             int p=move(root,dep[root]-dep[x]-1);
                             //cout<<"han "<<x<<" "<<root<<" "<<dep[root]-dep[x]-1<<endl;cout<<"p="<<p<<endl;
                             printf("%d
    ",dp[1]-dp[p]);
                         }
                         else printf("%d
    ",dp[x]);
                     }
                 }
             }
         }
         return 0;
    }
    

    正解应该是树状数组维护欧拉序列。,

    bit的神牛教的,,

    详见:点击打开链接


  • 相关阅读:
    cocos2dLua3.17.2当在出厂就为 Android11 Version30的手机上黑屏,无法运行的问题 qd
    cocos2dLua3.17.2 + AS3.5.2 创建工程成功 qd
    getdata软件的使用
    下载及安装Python详细步骤
    【硬件知识】电路图标识符号
    Java中高级开发工程师最新面试题整理
    jquery获得值和控制值
    js 根据日期做星座联动,简洁
    Android remove default apk
    registry collection: right click menu(右键菜单清理)/navigator pane(我的电脑左边栏清理)
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7284526.html
Copyright © 2011-2022 走看看