제출 #1344863

#제출 시각아이디문제언어결과실행 시간메모리
1344863walizamaneeTeam Coding (EGOI24_teamcoding)C++20
19 / 100
126 ms190336 KiB
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int boro = 200005;
ll vag = 1000000007;

int n , a[boro] , tim[boro] , chek[boro] , typ[boro] , one , two , ek , dui , k , ans , ansop;
int depth[boro] , borodepth[boro] , siz[boro] , amar[boro] , shobar[boro] , shuru[boro] , shesh[boro] , here;
int tans , tansop;

vector<int> adj[boro] , koi[boro]  ;

deque<int> sizz[boro];

multiset<int> ms;

void dfs( int me ){
    shuru[me] = here;
    here++;
    borodepth[me] = depth[me];
    if( ms.find(a[me]) == ms.end() ){
        chek[me] = 1;
    }
    else chek[me] = 0;

    ms.insert(a[me]);
    
    for( auto it : adj[me] ){
        depth[it] = depth[me] + 1;
        dfs( it );
        borodepth[me] = max( borodepth[me] , borodepth[it] );
    }

    ms.erase(ms.find(a[me]));
    shesh[me] = here;
}


void getboro( int me , int col ){
    siz[depth[me]]++;
    if( a[me] == col ) amar[depth[me]]++;
    for( auto it : adj[me] ) getboro( it , col );
}


void getchoto( int me ){

    for( auto it : adj[me] ){
        getchoto( it );

        if( (int)sizz[me].size() < (int)sizz[it].size() ) swap( sizz[me] , sizz[it] );
        for( int z = 0; z < (int)sizz[it].size(); z++ ){
            sizz[me][z] += sizz[it][z];
        }
    }
    sizz[me].push_front(1);

    if( tim[a[me]] == 0 && chek[me] == 1 ){
        // after each process reset
        for(  auto it: koi[a[me]] ){
            if( (depth[it] >= depth[me]) && (depth[it] <= borodepth[me])  ){
            amar[depth[it] - depth[me]] = 0;
            shobar[depth[it] - depth[me]] = 0;
            }
        }
        for(  auto it: koi[a[me]] ){
            if( (depth[it] >= depth[me]) && (depth[it] <= borodepth[me])  ){
            shobar[depth[it] - depth[me]]++;
            if( shuru[it] >= shuru[me] && shuru[it] <= shesh[me] ) amar[depth[it] - depth[me]]++;
            }
        }
        tans = 0;
        tansop = 0;
        for(  auto it: koi[a[me]] ){
            if( (depth[it] >= depth[me]) && (depth[it] <= borodepth[me])  ){
                one = depth[it] - depth[me];

                if( shobar[one] != 0 ){
                    int lol = min( sizz[me][one] , shobar[one] );
                    tans += lol;
                    tansop += (lol - amar[one]);
                    shobar[one] = 0;
                }

            }
        }

        if( ans < tans ){
            ans = tans;
            ansop = tansop;
        }
        else if( ans == tans ) ansop = min( ansop , tansop );

    }
}




int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    
    cin >> n >> k;

    for( int z = 0; z < n; z++ ){
        cin >> a[z];
        koi[a[z]].push_back(z);
        tim[a[z]]++;
    }
    
    int nn = (int)(sqrt(n));
    for( int z = 0; z < k; z++ ){
        if( tim[z] >= nn ) typ[z] = 1;
        else {
            typ[z] = 0; // rememver to consider size 0;
        }
    }

    for( int z = 1; z < n; z++ ){
        cin >> one;
        adj[one].push_back(z);
    }

    depth[1] = 1;
    here = 0;
    dfs( 0 );
    ans = (int)koi[a[0]].size();
    ansop = 0;


    // here is boro check
    for( int z = 0; z < k; z++ ){
        if( typ[z] == 1 ){
            for( int y = 1; y <= n; y++ ){
                shobar[y] = 0;
            }

            for( auto it : koi[z] ){
                shobar[depth[it]]++;
            }

            for( auto it: koi[z] ){
                if( chek[it] == 1 ){
                    for( int y = depth[it]; y <= borodepth[it]; y++ ){
                        amar[y] = 0;
                        siz[y] = 0;
                    }

                    getboro(it , a[it]);

                    tans = 0;
                    tansop = 0;

                    for( int y = depth[it]; y <= borodepth[it]; y++ ){
                        int lol = min( siz[y] , shobar[y] );
                        tans += lol;
                        tansop += (lol - amar[y]);
                    }

                    if( ans < tans ){
                        ans = tans;
                        ansop = tansop;
                    }
                    else if( ans == tans ) ansop = min( ansop , tansop );
                }
            }

        }
    }

    getchoto( 0 );

    cout << ans << " " << ansop << "\n";

    return 0;
}
/*
// sqrt decomp
    // process small and big differently
    // have 3 - size of depth , what i have , what is total
    // get dfs order 
    // get which ones we need to check with set
    // start end
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...