HDU-3078-Network(LCA+暴力排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3078

题目大意:给出n个节点,n-1条边,q次询问。每个节点都有自己的值。然后是n-1条边。之后是q次查询,有两种状态,k==0,将a的值赋为b,k>0查询a~b最短路上面第k大的值。

思路:正解不会,看着测试数据非常水,就LCA,暴力排序,O(q*n*logn):24*1e8*longn的复杂度,1ms,这就过了?果然还是测试数据水啊。

ACCode:

// luogu-judger-enable-o2
//#pragma comment(linker, "/STACK:1024000000,1024000000")
 
#include<stdio.h>
#include<string.h>
#include<math.h>
 
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
 
#define ll long long
#define Pair pair<ll,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
//  register
const int MAXN=8e4+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);

struct Node{
    ll v,val,nxt;
    Node(ll _v=0,ll _val=0,ll _nxt=0){
        v=_v;val=_val;nxt=_nxt;
    }
};
Node Edge[MAXN<<2];
ll Head[MAXN],Ecnt;
ll Fa[MAXN][30],Len[MAXN][30];
ll Deep[MAXN],Delay[MAXN];
ll Ans[MAXN],tot;
ll n,m,q;

void Intt(){
    clean(Head,-1);Ecnt=0;
    clean(Fa,-1);clean(Len,0);
    clean(Deep,0);
}
void Add(ll u,ll v,ll val){
    Edge[Ecnt]=Node(v,val,Head[u]);
    Head[u]=Ecnt++;
}
void DFS(ll u,ll fa){
    for(ll i=Head[u];i+1;i=Edge[i].nxt){
        ll temp=Edge[i].v;
        if(temp==fa) continue;
        if(Deep[temp]==0){
            Deep[temp]=Deep[u]+1;
            Fa[temp][0]=u;Len[temp][0]=Edge[i].val;
            ll up=0,pre=u;
            while(Fa[pre][up]>=0){
                Fa[temp][up+1]=Fa[pre][up];
                Len[temp][up+1]=Len[temp][up]+Len[pre][up];
                pre=Fa[pre][up++];
            }DFS(temp,u);
        }
    }
}
ll LCA(ll a,ll b){
    ll ans=0;
    if(Deep[a]<Deep[b]) swap(a,b);
    ll lim=log2(1.0*Deep[a])+1;
    for(ll i=lim;i>=0;--i){
        if(Deep[Fa[a][i]]>=Deep[b]){
            ans+=Len[a][i];
            a=Fa[a][i];
        }
    }
//    cout<<a<<" "<<b<<" "<<ans<<endl;
    if(a==b) return a;
    for(ll i=lim;i>=0;--i){
        if(Fa[a][i]!=Fa[b][i]){
            ans+=Len[a][i]+Len[b][i];
            a=Fa[a][i];b=Fa[b][i];
        }
    }
    if(Fa[a][0]==Fa[b][0]) return Fa[a][0];
    return -1;
}
int Cmp(ll a,ll b){
    return a>b;
}
void Solve(ll k,ll a,ll b){
    ll rt=LCA(a,b);
//    printf("rt=%lld\n",rt);
    if(Deep[a]-Deep[rt]+Deep[b]-Deep[rt]+1<k){
        printf("invalid request!\n"); return ;
    }tot=0;
    while(a!=rt){
        Ans[++tot]=Delay[a];
        a=Fa[a][0];
    }
    while(b!=rt){
        Ans[++tot]=Delay[b];
        b=Fa[b][0];
    }Ans[++tot]=Delay[rt];
//    printf("tot: %lld,",tot);
//    for(int i=1;i<=tot;++i){
//        printf("%lld ",Ans[i]);
//    }printf("\n");
    sort(Ans+1,Ans+tot+1,Cmp);
    printf("%lld\n",Ans[k]);
}
int main(){
    scanf("%lld%lld",&n,&m);Intt();
    for(ll i=1;i<=n;++i){
        scanf("%lld",&Delay[i]);
    }
    for(ll i=1;i<n;++i){
        ll a,b;scanf("%lld%lld",&a,&b);
        Add(a,b,1);Add(b,a,1);
    }Deep[1]=1;DFS(1,-1);
    while(m--){
        ll k,a,b;scanf("%lld%lld%lld",&k,&a,&b);
        if(k==0) Delay[a]=b;
        else Solve(k,a,b);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40482358/article/details/89575698