Luogu P3237 [HNOI2014]米特运输 题解
Description
题目链接
又臭又长的题面差评
给定一棵树,该树满足一定的性质:
- 节点 x 的所有子节点权值必须相等
- 节点 x 的所有子节点的权值之和等于 x 的权值
Solution
设第 x 个节点的权值为 v,它有 sz[x] 个直系子节点,显然,这 sz[x] 个直系子节点的权值均为 frac{v}{sz[x]}。
考虑设 f[i] 表示第 i 个节点不修改时的根节点的权值。
显然可得根节点的权值为:
那么只要计算出 1 到 n 的 f[i],判断相等个数即可。
由于乘法可能会爆 long long,所以开个 map 并 mod 一下。
Code
代码语言:javascript复制#include<cstdio>
#include<vector>
#include<map>
#define LL long long
#define max(x,y) ((x)>(y)?(x):(y))
#define W while
#define I inline
#define ig(c) ('0'<=(c)&&(c)<='9')
#define gc getchar
I int read(){int x=0,f=1;char c=gc();W(!ig(c)) f=c=='-'?-1:f,c=gc();W(ig(c)) x=(x<<3) (x<<1) (c&15),c=gc();return x*f;}
I void write(int x){x<0&&(putchar('-'),x=-x,0),x<10?(putchar(x '0'),0):(write(x/10),putchar(x '0'),0);}
const int N=500010,mod=19260817;
int n,a[N],f[N],ans;
std::vector<int> v[N];
std::map<int,int> mp;
I void dfs(int x,int fa,int sum){
int s=0;for(auto i:v[x]) (i^fa)&&(s ,0);
mp[(int)(1ll*sum*a[x]%mod)];
ans=max(ans,mp[(int)(1ll*sum*a[x]%mod)]);
sum=1ll*sum*s%mod;
for(auto i:v[x]) (i^fa)&&(dfs(i,x,sum),0);
}
int main(){
n=read();for(int i=1;i<=n;i ) a[i]=read();
for(int x,y,i=1;i<n;i ) x=read(),y=read(),v[x].push_back(y),v[y].push_back(x);
mp.clear();dfs(1,0,1ll);
return write(n-ans),0;
}