Title:
An unrooted tree with a point weight defines a special point: the point weight on the path from this point to any point on the tree is not repeated. Ask the number of special points.
answer:
Because of the uniqueness of the path of the two points on the tree, for two points with the same weights u 1, u 2 u_1,u_2u1,u2Obviously, only the point between these two points can be regarded as a special point. Because the points at both ends, for example, u 1 u_1u1Point at one end, it goes to u 2 u2The path of u 2 must pass throughu 1 u1u 1 , it will cause the point weight to be repeated.
Take any one as the root node. Define special value: only the special value of the special point is 0. We consider the current node uuu . The tree will be divided into three parts, the point setA = {x ∣ dfn [x] <dfn [u]} A=\{x|dfn[x]<dfn[u]\}A={ x∣dfn[x]<d f n [ u ] } , which is inuuu has traversed points before; point setB = {x ∣ x is a node on u subtree} B=\{x|x is a node on u subtree\}B={ X | X is u sub- tree on the section points } ; point setC = {x | x ∉ AC={ x∣x∈/A∨B } , that is, it has not been traversed yet, notuuThe node of the u subtree.
- ∃ x ∈ A ∨ C , a [ x ] = a [ u ] \exists x\in A\lor C ,a[x]=a[u] ∃x∈A∨C,a[x]=a [ u ] , thenBBAll points in B are not special points. WilluuAdd 1 to the special value of all points on the u subtree.
- ∀ x ∈ A ∨ C , a [ x ] ≠ a [ u ] ; ∃ y ∈ B ∩ y ≠ u , a [ y ] = a [ u ] \forall x\in A\lor C,a[x]\neq a[u];\exists y\in B \cap y\neq u,a[y]=a[u] ∀x∈A∨C,a[x]=a[u];∃y∈B∩and=u ,to [ and ]=a [ u ] , thenyyThere are special points in the son subtree where y is located, andA, CA, CA , C sumuuAll the points of all other son subtrees of u are not special points. Add 1 to the special value of all points on the tree, and then addyyThe special value of the son subtree where y is located is reduced by 1. Because it is traversing toyyy , according to 1.,yyhas beenThe special value of the subtree of y is increased by 1, and onlyuuis realizedu到yyThe special value of the point in the middle of y has not changed.
Observation found that each change of the special value is carried out in the unit of subtree . Difference on the tree .
For the realization of 1., first preprocess the number of occurrences of all point weights mp 1 mp1m p 1 , usemp 2 mp2m p 2 records the number of occurrences of point weights during traversal. Traverse touuWhen u , you can recordtmp = mp 2 [a [u]] tmp=mp2[a[u]]tmp=m p 2 [ a [ u ] ] , stands forAAA Midpointa [u] a [u]a [ u ] the number of points; after traversinguuAfter the subtree of u , at this timemp 2 [a [u]] mp2[a[u]]m p 2 [ a [ u ] ] meansA ∨ BA\lor BA∨B ina [u] a [u]The number of occurrences of a [ u ] ; thenmp 2 [a [u]] − tmp mp2[a[u]]-tmpmp2[a[u]]−t m p stands forBBB ina [u] a [u]The number of occurrences of a [ u ] . Ifmp 2 [a [u]] − tmp <mp 1 [a [u]] mp2[a[u]]-tmp<mp1[a[u]]mp2[a[u]]−tmp<m p 1 [ a [ u ] ] , indicating thatA ∨ CA\lor CA∨The point weight in C isa [u] a[u]At the point of a [ u ] , go to 1..
AC code:
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define lep(i,a,b) for(int i=(a);i>=(b);i--)
#define sci(x) scanf("%d",&(x))
#define scl(x) scanf("%lld",&(x))
#define scs(x) scanf("%s",(x))
#define pri(x) printf("%d\n",(x))
#define prl(x) printf("%lld\n",(x))
#define prs(x) printf("%s\n",(x))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define All(x) x.begin(),x.end()
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define INFF 0x3f3f3f3f3f3f3f3f
#define multi int T;scanf("%d",&T);while(T--)
using namespace std;
typedef long long ll;
typedef double db;
const int N=2e5+5;
const int mod=10007;
const db eps=1e-6;
const db pi=acos(-1.0);
int n,cnt=0,a[N],dfn[N],sz[N],num[N];
map<int,int>mp1,mp2;
vector<int>tr[N];
void upd(int st,int ed,int val){
num[st]+=val;
num[ed+1]-=val;
}
void dfs(int u,int fa=-1){
dfn[u]=++cnt;
sz[u]=1;
int tmp=mp2[a[u]];
++mp2[a[u]];
for(auto v:tr[u]){
if(v==fa) continue;
int cur=mp2[a[u]];
dfs(v,u);
if(mp2[a[u]]!=cur){
upd(dfn[v],dfn[v]+sz[v]-1,-1);
upd(1,n,1);
}
sz[u]+=sz[v];
}
tmp=mp2[a[u]]-tmp;
if(tmp<mp1[a[u]]) upd(dfn[u],dfn[u]+sz[u]-1,1);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("D:\\work\\data.in","r",stdin);
#endif
cin>>n;
rep(i,1,n){
cin>>a[i];
++mp1[a[i]];
}
rep(i,1,n-1){
int x,y;
cin>>x>>y;
tr[x].push_back(y);
tr[y].push_back(x);
}
dfs(1);
int ans=0;
rep(i,1,n){
num[i]+=num[i-1];
if(!num[i]) ++ans;
}
cout<<ans<<endl;
}