Cod sursa(job #2438302)

Utilizator CharacterMeCharacter Me CharacterMe Data 12 iulie 2019 10:27:12
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
using namespace std;
int n, m, i, j, cnt[100001], vf, height[100001], val[100001], sq, add[320], inv_cnt[100001];
int task_nr, task_val, task_node;
bitset<320> check[1000001];
vector<int> graph[100001];
void task_1();
void task_2();
void dfs(int node);
int main()
{
    freopen("arbore.in", "r", stdin);
    freopen("arbore.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(i=1; i<n; ++i){
        int x, y;
        scanf("%d%d", &x, &y);
        graph[x].push_back(y);
    }
    for(i=1; i<=sq+2; ++i) check[0][i]=true;
    dfs(1);
    for(i=1; i<=n; ++i) --height[i];
    sq=sqrt(n);
    for(i=1; i<=m; ++i){
        scanf("%d%d", &task_nr, &task_node);
        if(task_nr==1) {scanf("%d", &task_val); task_1();}
        else task_2();

    }
    return 0;
}
void dfs(int node){
    cnt[node]=++vf;
    inv_cnt[vf]=node;
    for(auto i:graph[node]) {dfs(i); height[node]+=height[i];}
    ++height[node];
    return;
}
void task_1(){
    int first, last;
    first=cnt[task_node], last=cnt[task_node]+height[task_node];
    if(first%sq!=1){
        int second=first;
        if(first%sq==0) --first;
        for(j=first/sq*sq+1; j<=min((first/sq+1)*sq, n); ++j) check[val[j]][first/sq+1]=false;
        for(j=second; j<=min((first/sq+1)*sq, n); ++j) {val[j]+=task_val; check[val[j]][first/sq+1]=true;}
        for(j=first/sq*sq+1; j<second; ++j) check[val[j]][first/sq+1]=true;
        first=second;
        if(first%sq==0) first=first/sq+1;
        else first=first/sq+2;
    }
    else first=first/sq+1;
    if(last%sq!=0){
        for(j=last/sq*sq+1; j<=min((last/sq+1)*sq, n); ++j) check[val[j]][last/sq+1]=false;
        for(j=last/sq*sq+1; j<=last; ++j) {val[j]+=task_val; check[val[j]][last/sq+1]=true;}
    }
    last/=sq;
    for(j=first; j<=last; ++j) add[j]+=task_val;
    return;
}
void task_2(){
    int last=n;
    if(last%sq==0) last/=sq;
    else last=last/sq+1;
    for(j=1; j<=last; ++j) if(check[task_node-add[j]][j]==true) {
        for(int k=(j-1)*sq+1; k<=j*sq; ++k) if(val[k]+add[j]==task_node) {printf("%d\n", inv_cnt[k]); return;}
    }
    printf("-1\n");
    return;
}