php做网站的分站,wordpress边下边看,网站域名实名认证查询,国外网站搭建登录—专业IT笔试面试备考平台_牛客网
题意#xff1a; 思路#xff1a;
这个虽然是树形DP#xff0c;却用了换根的思想....
首先#xff0c;后缀0的个数可以转化成min(cnt2,cnt5)#xff0c;其中cnt2为2的因子个数#xff0c;cnt5为5的因子个数
然后进行DP
设dp[u]…登录—专业IT笔试面试备考平台_牛客网
题意 思路
这个虽然是树形DP却用了换根的思想....
首先后缀0的个数可以转化成min(cnt2,cnt5)其中cnt2为2的因子个数cnt5为5的因子个数
然后进行DP
设dp[u][0/1]为在除了u这棵子树中2/5的因子个数
为什么要这么设计我们发现如果计算的结点是在子树里面的那么lca就是u子树的贡献直接就是sz[u]*cnt[u][0/1]
但是在这棵子树之外的贡献不能这么求因此需要额外设计
然后转移就很简单
dp[v][j]dp[u][j](sz[u]-sz[v])*cnt[u][j]
最后统计贡献的时候加上子树部分的贡献取min(cnt2,cnt5)就好了
Code
#include bits/stdc.h#define int long longusing namespace std;const int mxn2e510;
const int mxe1e610;
const int mxv1e610;
const int mod998244353;
const int Inf1e18;vectorint G[mxn];int N,Q;
int u,v,x;
int sz[mxn];
int dp[mxn][2],cnt[mxn][2];void init(){for(int i1;iN;i){if(i%20){int ti,s0;while(t%20) t/2,s;cnt[i][0]s;}if(i%50){int ti,s0;while(t%50) t/5,s;cnt[i][1]s;}}
}
void dfs1(int u,int fa){sz[u]1;for(auto v:G[u]){if(vfa) continue;dfs1(v,u);sz[u]sz[v];}
}
void dfs2(int u,int fa){for(auto v:G[u]){if(vfa) continue;for(int j0;j1;j){dp[v][j]dp[u][j](sz[u]-sz[v])*cnt[u][j];}dfs2(v,u);}
}
void solve(){cinNQ;init();for(int i1;iN-1;i){cinuv;G[u].push_back(v);G[v].push_back(u);}dfs1(1,0);dfs2(1,0);while(Q--){cinx;int res1e18;for(int j0;j1;j){resmin(res,dp[x][j]sz[x]*cnt[x][j]);}coutres\n;}
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int __1;//cin__;while(__--)solve();return 0;
}