Cod sursa(job #1479288)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 30 august 2015 23:22:34
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.2 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <cmath>
#include <algorithm>
using namespace std;
 
void make_euler(const int cur, const int prev,
    const vector<vector<int> >& vec,
    vector<int>& euler,
    vector<pair<int, int> >& st_fin){
    euler.push_back(cur);
    st_fin[cur].first = euler.size()-1;
    for(const auto next : vec[cur]){
        if(next != prev){
            make_euler(next, cur, vec, euler, st_fin); } }
    euler.push_back(cur);
    st_fin[cur].second = euler.size()-1; }
 
class the_structure{
    const int chunk_sz, nr_chunks;
    vector<int> buf, which_chunk;
    struct chunk_info{
        int st, dr;
		bitset<1000001> apare = 1;
        int delta = 0; };
    vector<chunk_info> chunks;
    void redo_chunk(const int ch){
		auto& this_chunk = chunks[ch];
		this_chunk.apare = 0;
        for(int i = chunks[ch].st; i <= chunks[ch].dr; ++i){
            this_chunk.apare[buf[i]] = true; } }
public:
    the_structure(const int n):
        chunk_sz(ceil(sqrt(n))), nr_chunks(ceil(float(n)/chunk_sz)),
        buf(n), which_chunk(n), chunks(nr_chunks){
 
        for(int i = 0; i < nr_chunks; ++i){
			auto& this_chunk = chunks[i];
            for(int j = 0; j < chunk_sz && j + this_chunk.st < n; ++j){
                which_chunk[this_chunk.st+j] = i; }
        	this_chunk.dr = min(this_chunk.st + chunk_sz - 1, n-1); } }
     
    void update(const int st, const int dr, const int val){
        const int st_chunk_ind = which_chunk[st], dr_chunk_ind = which_chunk[dr];
		auto& st_chunk = chunks[st_chunk_ind], dr_chunk = chunks[dr_chunk_ind];
        if(st_chunk_ind != dr_chunk_ind){
            for(int i = st; i <= st_chunk.dr; ++i){
                buf[i] += val; }
            for(int i = dr_chunk.st; i <= dr; ++i){
                buf[i] += val; }
            redo_chunk(st_chunk_ind);
            redo_chunk(dr_chunk_ind); }
        else{
            for(int i = st; i <= dr; ++i){
                buf[i] += val; }
            redo_chunk(st_chunk_ind); }
        for(int i = st_chunk_ind+1; i < dr_chunk_ind; ++i){
            chunks[i].delta += val; } }
     
    int query(const int val){
        for(int ch = 0; ch < nr_chunks; ++ch){
			auto& this_chunk = chunks[ch];
            if(val - this_chunk.delta >= 0 && this_chunk.apare[val - this_chunk.delta]){
                for(int j = this_chunk.st; j <= this_chunk.dr; ++j){
                    if(buf[j] + this_chunk.delta == val){
                        return j; } } } }
        return -1; } };
 
int main(){
    ifstream f("arbore.in");
    ofstream g("arbore.out");
    int n, m;
    f >> n >> m;
    vector<vector<int> > vec(n);
    for(int i = 0, a, b; i < n-1; ++i){
        f >> a >> b;
        --a, --b;
        vec[a].push_back(b);
        vec[b].push_back(a); }
    vector<int> euler;
    vector<pair<int, int> > st_fin(n, {0, 0});
    make_euler(0, -1, vec, euler, st_fin);
    the_structure ts(euler.size());
    for(int i = 0, t, p, s; i < m; ++i){
        f >> t;
        if(t == 1){
            f >> p >> s;
            --p;
            ts.update(st_fin[p].first, st_fin[p].second, s); }
        else{
            f >> s;
            const int rez = ts.query(s);
            g << (rez != -1 ? euler[rez]+1 : -1) << '\n'; } }
    return 0; }