牛客多校9 HHere is an Easy Problem of Zero-chan 【树形DP好题】【树的遍历】【如何建立一棵树】

8 篇文章 0 订阅

 

 

 

#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;
//#define map unordered_map
inline __int128 read() {
    __int128 x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch>'9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

inline void print(__int128 x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9)print(x / 10);
    putchar(x % 10 + '0');
}

#define int long long
typedef pair<int,int> PII;
const int N = 1e5 + 10, M = N << 1;
int n, q;
int h[N], e[M], ne[M], idx;
//int fa[N][18];
int father[N];
int depth[N];
int sz[N];
PII co[N];
int co2,co5;



PII cal(int a)
{
    int n=0,m=0;
    
    while(a%5==0)
    {
        a/=5;
        m++;
    }
    
   while(a%2==0)
   {
       a/=2;
       n++;
   }
    
    PII t={m,n};
    
    return t;
}


void init()
{
    for(int i=1;i<N;i++)
    {
       PII t=cal(i);
       co[i].x=t.x;
       co[i].y=t.y;
    }
}

void cal2(int a,int k)
{
    co2+=co[a].first*k;
    co5+=co[a].second*k;
    
}


void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

__int128 dfs1(int u, int f) {
    depth[u] = depth[f] + 1;
    sz[u] = 1;
    father[u] = f;

    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == f) continue;
        sz[u] += dfs1(j, u);
    }
    return sz[u];
}



int qry[N];

signed main()
{
    
  init();
  scanf("%d%d",&n,&q);
    int t = n - 1;
    memset(h, -1, sizeof h);
    while (t--)
    {
        int u, v; scanf("%lld%lld", &u, &v);
        add(u, v), add(v, u);
    }
    dfs1(1, 0);
/*
    puts("sz");
    for (int i = 1; i <= n; ++i)
    {
        cout << "sz[i] " << sz[i] << endl;
    }
*/
    father[1] = 0;
    for (int i = 1; i <= q; ++i)
    {
         co2=0,co5=0;
        int x;
        scanf("%lld", &x);

        cal2(x, sz[x]);
       // cout << res << endl;
      
        while (father[x] != 0)
        {
            int son = x;
            x = father[x];
            cal2(x, sz[x] - sz[son]);
        }
    
      

        printf("%lld\n", min(co2,co5));
    }




    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值