Bzoj3574

每两个点之间的比值都是定的。

多个数乘起来可能会爆 ll。

所以一般有两种解决办法:

  • 哈希
  • 转 $\log$ ,加起来

因为机房最近全在卡hash,所以我第一时间想到的也是hash

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<bits/stdc++.h>
#define maxn 500005
#define int long long
#define ull unsigned long long
#define put() putchar('\n')
using namespace std;
inline void read(int &x){
int f=1;x=0;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
x*=f;
}
const int mod=998244353,mod2=1e9+7;
struct node{
int x,y;ull z;
node(int a=0,int b=0,ull c=0) {x=a;y=b;z=c;}
bool operator <(const node &a) const{return x==a.x?(y==a.y?z<a.z:y<a.y):x<a.x;}
bool operator ==(const node &a) const{return x==a.x&&y==a.y&&z==a.z;}
}id[maxn];
map<node,int>mp;
int n,w[maxn],out[maxn],g[maxn][2];
ull f[maxn];
int h[maxn],head=1;
struct yyy{
int to,z;
inline void add(int x,int y) {
to=y;z=h[x];h[x]=head;
}
}a[maxn*2];
int ans,sum;
const double eps=1e-1;
inline void dfs(int x,int pre) {
int i;
id[x]=node(w[x]*g[x][0]%mod,w[x]*g[x][1]%mod2,f[x]*w[x]);
for (i=h[x];i;i=a[i].z)
if (a[i].to^pre) {
g[a[i].to][0]=g[x][0]*out[x]%mod;
g[a[i].to][1]=g[x][1]*out[x]%mod2;
f[a[i].to]=f[x]*out[x];
dfs(a[i].to,x);
}
}
signed main(void){
int i,x,y;
read(n);
for (i=1;i<=n;i++) read(w[i]),out[i]=-1;out[1]++;
for (i=1;i<n;i++) {
read(x);read(y);
out[x]++;a[++head].add(x,y);
out[y]++;a[++head].add(y,x);
}
g[1][0]=g[1][1]=1;f[1]=1;dfs(1,0);
sort(id+1,id+1+n);
for (i=1;i<=n;i++) if (id[i]==id[i-1]) sum++;else ans=max(ans,sum),sum=1;
printf("%lld",n-max(ans,sum));
return 0;
}