看懂了题目就A了一半。。。
大意是这样的,给一棵以1为根的树,求最少修改几个点的容量后,使得除根节点外所有节点为父亲容量/父亲的儿子个数。
因为1个节点确定,所有节点都确定了,不妨对每个点求出它不修改时根节点的容量,Hash一下就可以了。(貌似自然溢出会WA,可能我写炸了吧)
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define N 500005
#define A 1000000007
#define B 20000909
using namespace std;
int n,a[N],x,y,first[N],next[N<<1],to[N<<1],l,Ans,d[N],fa[N];
struct Hash{ll a,b;}k[N];
bool operator<(Hash x,Hash y)
{
if (x.a!=y.a) return x.a<y.a;
return x.b<y.b;
}
bool operator==(Hash x,Hash y)
{
return x.a==y.a&&x.b==y.b;
}
int Re()
{
char c=getchar();int x=0;
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
void link(int x,int y)
{
to[++l]=y;next[l]=first[x];first[x]=l;d[x]++;
to[++l]=x;next[l]=first[y];first[y]=l;d[y]++;
}
void dfs(int x)
{
Hash t;
t.a=k[x].a*d[x]%A;
t.b=k[x].b*d[x]%B;
for (int i=first[x];i;i=next[i])
if (to[i]!=fa[x]) fa[to[i]]=x,k[to[i]]=t,dfs(to[i]);
k[x]=(Hash){k[x].a*a[x]%A,k[x].b*a[x]%B};
}
int main()
{
n=Re();
for (int i=1;i<=n;i++)
a[i]=Re();
for (int i=2;i<=n;i++)
x=Re(),y=Re(),link(x,y),d[i]--;
k[1]=(Hash){1,1};dfs(1);
sort(k+1,k+n+1);
for (int i=1,j;i<=n;i=j+1)
{
for (j=i;j<n&&k[j+1]==k[i];j++);
Ans=max(Ans,j-i+1);
}
printf("%d\n",n-Ans);
return 0;
}