void hld(int node, int par){ if(chain_head[chain_no] == -1) chain_head[chain_no] = node; //assigning the head chain_idx[node] = chain_no; chain_pos[node] = chain_size[chain_no]; chain_size[chain_no]++; int idx = -1; int sub_sz = -1; for(auto v : g[node]){ if(v == par) continue; if(sz[v] > sub_sz){ idx = v; sub_sz = sz[v]; } } if(idx != -1) hld(idx, node); for(auto v : g[node]){ if(v == par) continue; if(v != idx){ chain_no++; hld(v, node); } } }
// gives a 1-index to each node such that indices // in each heavy path are contiguous void hld(int u, int p = 0) { static int index = 0; hld_index[u] = ++index; hld_order[hld_index[u]] = X[u]; if (!hld_root[u]) hld_root[u] = u; if (hld_child[u]) { hld_root[hld_child[u]] = hld_root[u]; hld(hld_child[u], u); } for (auto v : g[u]) if (v != p && v != hld_child[u]) hld(v, u); }
void bin_index_t::save_items_count() { fs::path file_name=fs::path(base_dir)/items_count_file_name; FILE* f=fopen(file_name.string().c_str(),"wb"); if(!f)throw std::runtime_error("could not open items count file for write: "+file_name.string()); file_hldr hld(f); #ifdef _WIN32 if(fprintf(f,"%u",items_count)<0) #else if(fprintf(f,"%llu",items_count)<0) #endif throw std::runtime_error("could not write items count: "+file_name.string()); }
void hld(int cur) { if(chainHead[chainNo] == -1) chainHead[chainNo]=cur; chainInd[cur] = chainNo; chainPos[cur] = chainSize[chainNo]; chainSize[chainNo]++; int ind = -1,mai = -1; for(int i = 0; i < adj[cur].sz; i++) { if(subsize[ adj[cur][i] ] > mai) { mai = subsize[ adj[cur][i] ]; ind = i; } } if(ind >= 0) hld( adj[cur][ind] ); for(int i = 0; i < adj[cur].sz; i++) { if(i != ind) { chainNo++; hld( adj[cur][i] ); } } }
void bin_index_t::load_items_count() { fs::path file_name=fs::path(base_dir)/items_count_file_name; if(!fs::exists(file_name))return; FILE* f=fopen(file_name.string().c_str(),"rb"); if(!f)throw std::runtime_error("could not open items count file for read: "+file_name.string()); file_hldr hld(f); #ifdef _WIN32 if(fscanf(f,"%u",&items_count)!=1) #else if(fscanf(f,"%lluu",&items_count)!=1) #endif throw std::runtime_error("could not read items count: "+file_name.string()); }