【LCA】 HDU 3078 Network

题意: 一棵树 点有权值

求u-v 的路径上 第 k 大的点权值(包括u和v)

k==0 为更改操作

先LCA 转 RMQ  

如果u==v 判断k==1 

否则 求 (u,v)的LCA 然后 求u的前驱 和v的前驱 并且把权值存起来

把权值排序 然后输出


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <map>
#define cler(arr, val)    memset(arr, val, sizeof(arr))
typedef long long  LL;
const int MAXN = 100000+6;
const int MAXM = 140000;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
int dp[MAXN*2][25];
struct node
{
    int v,next;
}edge[MAXN*2];
int len[MAXN];
int head[MAXN],tol,first[MAXN],time,vis[MAXN*2],dep[MAXN*2],pre[MAXN];
void addedge(int u,int v)
{
    edge[tol].v=v;
    edge[tol].next=head[u];
    head[u]=tol++;
}
void RMQ_init(int n)
{
    for(int i = 1; i <= n; i++)
    {
        dp[i][0] = i;
    }
    for(int j=1;(1<<j)<=n;j++)
    {
        for(int i=1;i+(1<<j)-1<=n;i++)
        {
                dp[i][j] = dep[dp[i][j-1]] <
                           dep[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1];
        }
    }
}
int RMQ(int l,int r)
{
    int k=(int)(log(double(r-l+1))/log((double)2));
    return dep[dp[l][k]] <= dep[dp[r-(1<<k)+1][k]]?dp[l][k]:dp[r-(1<<k)+1][k];
}
void dfs(int u,int pr,int deep)
{
    vis[++time]=u;
    dep[time]=deep;
    first[u]=time;
    for(int i=head[u];~i;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==pr) continue;
        pre[v]=u;
        dfs(v,u,deep+1);
        vis[++time]=u;
        dep[time]=deep;
    }
}
void init()
{
    cler(head,-1);
    tol=0;
    time=0;
}
vector<int>g;
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    int n,m,k;
    while(cin>>n>>m)
    {
        init();
        int a,b,c;
        for(int i=1;i<=n;i++)
            scanf("%d",&len[i]);
        for(int i=0;i<n-1;i++)
        {
            scanf("%d%d",&a,&b);
            addedge(a,b);
            addedge(b,a);
        }
        dfs(1,0,0);
        RMQ_init(time);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&k,&a,&b);
            if(k==0)
                len[a]=b;
            else
            {
                if(a==b)
                {
                    if(k==1) printf("%d\n",len[a]);
                    else puts("invalid request!");
                }
                else
                {
                    g.clear();
                    int u=first[a],v=first[b];
                    if(u>v) swap(u,v);
                    int c=RMQ(u,v);
                    c=vis[c];
                    g.push_back(len[c]);
                    while(a!=c)
                    {
                        g.push_back(len[a]);
                        a=pre[a];
                    }
                    while(b!=c)
                    {
                        g.push_back(len[b]);
                        b=pre[b];
                    }
                    if(g.size()<k)
                        puts("invalid request!");
                    else
                    {
                        sort(g.begin(),g.end());
                        printf("%d\n",g[g.size()-k]);
                    }
                }
            }
        }
    }
    return 0;
}


posted @ 2014-11-08 10:53  kewowlo  阅读(136)  评论(0编辑  收藏  举报