Luogu P3237 [HNOI2014]米特运输 题解

Description

题目链接

又臭又长的题面差评

给定一棵树,该树满足一定的性质:

  1. 节点 $x$ 的所有子节点权值必须相等
  2. 节点 $x$ 的所有子节点的权值之和等于 $x$ 的权值

Solution

设第 $x$ 个节点的权值为 $v$,它有 $sz[x]$ 个直系子节点,显然,这 $sz[x]$ 个直系子节点的权值均为 $\frac{v}{sz[x]}$。

考虑设 $f[i]$ 表示第 $i$ 个节点不修改时的根节点的权值。

显然可得根节点的权值为:

$$ v[i] \times \prod sz[x] (x \in {fa}_v)$$

那么只要计算出 $1$ 到 $n$ 的 $f[i]$,判断相等个数即可。

由于乘法可能会爆 $long$ $long$,所以开个 $map$ 并 $mod$ 一下。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#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%10+'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;
}