CF1467E. Distinctive Roots in a Tree

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={ xdfn[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={ xx/AB } , that is, it has not been traversed yet, notuuThe node of the u subtree.

  1. ∃ x ∈ A ∨ C , a [ x ] = a [ u ] \exists x\in A\lor C ,a[x]=a[u] xAC,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.
  2. ∀ 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] xAC,a[x]=a[u];yBand=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 realizeduyyThe 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 BAB 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 CAThe 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;
}

Guess you like

Origin blog.csdn.net/Luowaterbi/article/details/112666065