Submission #475286

#TimeUsernameProblemLanguageResultExecution timeMemory
475286DeepessonRegions (IOI09_regions)C++17
75 / 100
5689 ms131076 KiB
#include <bits/stdc++.h>
#define MAXN 205000
#define REGIOES 25100
#define INI MAXN-5
#define SQRTN 450
int cores[MAXN],array[MAXN],primeiro[MAXN],size[MAXN],cur;
std::vector<int> con[MAXN];
std::vector<int> indices[REGIOES];
int N,R,Q;
int dfs(int pos,int prev){
    array[cur]=cores[pos];
    primeiro[pos]=cur;
    ++cur;
    int res=1;
    for(auto&x:con[pos]){
        if(x==prev)continue;
        res+=dfs(x,pos);
    }
    return size[pos]=res;
}
int tamanho[REGIOES];
bool grandes[REGIOES];
int indicegrandeza[REGIOES];
const int threshold = 167;///Mudar para SQRTN!!!!!!
int slots = 500;
int curg=0;
namespace big {
    int bucket[505][REGIOES];
    int tab[MAXN*4];
    void query(int l,int r,int la=0,int ra=INI,int pos=1){
        if(ra<l||la>r)return;
        if(la>=l&&ra<=r){
            ++tab[pos];
            return;
        }
        int m=(la+ra)/2;
        query(l,r,la,m,pos*2);
        query(l,r,m+1,ra,(pos*2)+1);
    }
    void build(int k,int la=0,int ra=INI,int pos=1){
        if(tab[pos]){
            for(int i=la;i!=ra+1;++i){
                bucket[k][array[i]]+=tab[pos];
            }
            tab[pos]=0;
        }
        if(la==ra)return;
        int m=(la+ra)/2;
        build(k,la,m,pos*2);
        build(k,m+1,ra,(pos*2)+1);
    }
    void preparar(void){
        for(int i=0;i!=REGIOES;++i){
            if(grandes[i]){
                for(auto&x:indices[i]){
                    query(primeiro[x],primeiro[x]+size[x]-1);
                }
                build(indicegrandeza[i]);
            }
        }
    }
    int consulta(int x,int y){
        return bucket[indicegrandeza[x]][y];
    }
}
typedef std::pair<int,int> pii;
namespace small {
    std::vector<pii> tab[MAXN*4];
    int query(int l,int r,int k,int la=0,int ra=INI,int pos=1){
        if(ra<l||la>r)return 0;
        if(la>=l&&ra<=r){
            int l=0,r=tab[pos].size()-1;
            while(l<r){
                int m = (l+r)/2;
                if(tab[pos][m].first>=k){
                    r=m;
                }else l=m+1;
            }
            if(tab[pos][l].first==k)return tab[pos][l].second;return 0;
        }
        int m=(la+ra)/2;
        return query(l,r,k,la,m,pos*2) +
        query(l,r,k,m+1,ra,(pos*2)+1);
    }
    void build(int la=0,int ra=INI,int pos=1){
        for(int i=la;i!=ra+1;++i){
            tab[pos].push_back({array[i],1});
        }
        std::sort(tab[pos].begin(),tab[pos].end());
        {
            std::vector<pii> novo_vetor;
            for(auto&x:tab[pos]){
                if(!novo_vetor.size()||novo_vetor.back().first!=x.first){
                    novo_vetor.push_back(x);
                }else ++novo_vetor.back().second;
            }
            tab[pos]=novo_vetor;
        }
        if(la==ra)return;
        int m=(la+ra)/2;
        build(la,m,pos*2);
        build(m+1,ra,(pos*2)+1);
    }
    int consulta(int a,int b){
        int res=0;
        for(auto&x:indices[a]){
            res+=query(primeiro[x],primeiro[x]+size[x]-1,b);
        }
        return res;
    }
};
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin>>N>>R>>Q;
    std::cin>>cores[0];
    indices[cores[0]].push_back(0);
    for(int i=1;i!=N;++i){
        int a,b;std::cin>>a>>b;--a;
        cores[i]=b;
        indices[b].push_back(i);
        tamanho[b]++;
        con[a].push_back(i);con[i].push_back(a);
    }
    std::vector<pii> tamanhos;

    for(int i=0;i!=REGIOES;++i){
        if(tamanho[i]>=1){
            tamanhos.push_back({tamanho[i],i});
        }
    }
    slots=std::min(slots,(int)tamanhos.size());
    std::sort(tamanhos.begin(),tamanhos.end(),std::greater<pii>());
    for(int i=0;i!=slots;++i){
        grandes[tamanhos[i].second]=true;
        indicegrandeza[tamanhos[i].second]=curg;curg++;
    }
    dfs(0,0);
    big::preparar();
    small::build();
    for(int i=0;i!=Q;++i){
        int a,b;
        std::cin>>a>>b;
        if(grandes[a]){
            std::cout<<big::consulta(a,b)<<std::endl;
        }else {
            std::cout<<small::consulta(a,b)<<std::endl;
        }
    }
}

Compilation message (stderr)

regions.cpp: In function 'int small::query(int, int, int, int, int, int)':
regions.cpp:79:13: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
   79 |             if(tab[pos][l].first==k)return tab[pos][l].second;return 0;
      |             ^~
regions.cpp:79:63: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
   79 |             if(tab[pos][l].first==k)return tab[pos][l].second;return 0;
      |                                                               ^~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...