zoukankan      html  css  js  c++  java
  • 美团 CodeM 复赛」城市网络

    美团 CodeM 复赛」城市网络

    内存限制:64 MiB时间限制:500 ms标准输入输出

    题目描述

    有一个树状的城市网络(即 nnn 个城市由 n−1n-1n1 条道路连接的连通图),首都为 111 号城市,每个城市售卖价值为 aia_iai​​ 的珠宝。

    你是一个珠宝商,现在安排有 qqq 次行程,每次行程为从 uuu 号城市前往 vvv 号城市(走最短路径),保证 vvv 在 uuu 前往首都的最短路径上。

    在每次行程开始时,你手上有价值为 ccc 的珠宝(每次行程可能不同),并且每经过一个城市时(包括 uuu 和 vvv),假如那个城市中售卖的珠宝比你现在手上的每一种珠宝都要优秀(价值更高,即严格大于),那么你就会选择购入。

    现在你想要对每一次行程,求出会进行多少次购买事件。

    输入格式

    第一行,两个正整数 n,qn , qn,q。

    第二行,nnn 个正整数 aia_iai​​ 描述每个城市售卖的珠宝的价值。

    接下来 n−1n-1n1 行,每行描述一条道路 x,yx , yx,y (1≤x,y≤n1 leq x , y leq n1x,yn),表示有一条连接 x 和 y 的道路。

    接下来 qqq 行,每行描述一次行程 u,v,cu , v , cu,v,c (1≤u,v≤n1 leq u , v leq n1u,vn)。

    输出格式

    对于每次行程输出一行,为所购买次数。

    样例

    样例输入

    5 4
    3 5 1 2 4
    1 2
    1 3
    2 4
    3 5
    4 2 1
    4 2 2
    4 2 3
    5 1 5

    样例输出

    2
    1
    1
    0

    数据范围与提示

    对于 100%100 \%100% 的数据,保证 2≤n≤105,1≤q≤1052 leq n leq 10^5 , 1 leq q leq 10^52n105​​,1q105​​ , 1≤ai≤1051 leq a_i leq 10^51ai​​105​​ , 1≤c≤1051 leq c leq 10^51c105​​。

    分析:有趣的技巧是把询问挂在起点下面当叶子;

       对于新树上的每个点找第一个比他大的祖先,可以倍增实现;

       对于一个点,第一个比他大的祖先得到之后又可以继续倍增;

       这样这个问题就完美解决了;

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <bitset>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cassert>
    #include <ctime>
    #define rep(i,m,n) for(i=m;i<=(int)n;i++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define sys system("pause")
    #define ls rt<<1
    #define rs rt<<1|1
    const int maxn=2e5+10;
    const int N=5e2+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;}
    int n,m,k,t,a[maxn],dep[maxn],to[maxn],fa[20][maxn];
    vi e[maxn];
    void dfs(int x,int y)
    {
        int pos=y;
        for(int i=19;i>=0;i--)if(fa[i][pos]&&a[fa[i][pos]]<=a[x])pos=fa[i][pos];
        if(a[pos]>a[x])fa[0][x]=pos;
        else fa[0][x]=fa[0][pos];
        for(int i=1;fa[i-1][fa[i-1][x]];i++)
        {
            fa[i][x]=fa[i-1][fa[i-1][x]];
        }
        dep[x]=dep[y]+1;
        for(int z:e[x])
        {
            if(z==y)continue;
            dfs(z,x);
        }
    }
    int main()
    {
        int i,j;
        int q;
        scanf("%d%d",&n,&q);
        rep(i,1,n)scanf("%d",&a[i]);
        rep(i,1,n-1)
        {
            scanf("%d%d",&j,&k);
            e[j].pb(k),e[k].pb(j);
        }
        rep(i,1,q)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[n+i]=z;
            e[n+i].pb(x);
            e[x].pb(n+i);
            to[n+i]=y;
        }
        dfs(1,0);
        rep(i,n+1,n+q)
        {
            int ret=0,pos=i;
            for(j=19;j>=0;j--)
            {
                if(dep[fa[j][pos]]>=dep[to[i]])
                {
                    ret+=(1<<j);
                    pos=fa[j][pos];
                }
            }
            printf("%d
    ",ret);
        }
        return 0;
    }
  • 相关阅读:
    94. Binary Tree Inorder Traversal
    101. Symmetric Tree
    38. Count and Say
    28. Implement strStr()
    实训团队心得(1)
    探索性测试入门
    LC.278. First Bad Version
    Search in Unknown Sized Sorted Array
    LC.88. Merge Sorted Array
    LC.283.Move Zeroes
  • 原文地址:https://www.cnblogs.com/dyzll/p/7156090.html
Copyright © 2011-2022 走看看