Cod sursa(job #2438330)

Utilizator CharacterMeCharacter Me CharacterMe Data 12 iulie 2019 11:46:40
Problema Arbore Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#define left first
#define right second
using namespace std;
int n, m, i, j, cnt[100001], vf, height[100001], val[100001], sq, add[320], inv_cnt[100001], k;
int task_nr, task_val, task_node;
bool check[1000010][340];
vector<int> graph[100001];
pair<int, int> cap[100001];
char c[50];
void task_1();
void task_2();
void dfs(int node, int dad);
int read();
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);
        graph[y].push_back(x);
    }
    for(i=1; i<=sq+2; ++i) check[0][i]=true;
    dfs(1, 0);
    k=1; sq=sqrt(n);
    for(i=1; i<=n; ++i) {--height[i]; cap[i].left=(k-1)*sq+1; cap[i].right=min(k*sq, n); if(i==cap[i].right) ++k;}
    fgetc(stdin);
    for(i=1; i<=m; ++i){
        k=-1;
        fgets(c, 50, stdin);
        task_nr=read(); task_node=read();
        if(task_nr==1) {task_val=read(); task_1();}
        else task_2();

    }
    return 0;
}
void dfs(int node, int dad){
    cnt[node]=++vf;
    inv_cnt[vf]=node;
    for(auto i:graph[node]) if(i!=dad){dfs(i, node); height[node]+=height[i];}
    ++height[node];
    return;
}
void task_1(){
    int first, last;
    first=cnt[task_node];
    last=first+height[task_node];
    if(cap[first].left==cap[last].left){
        int l=cap[first].left, r=cap[last].right, team=r/sq;
        for(j=l; j<=r; ++j) check[val[j]][team]=false;
        for(j=l; j<=r; ++j) {
            if(j>=first && j<=last) val[j]+=task_val;
            check[val[j]][team]=true;
        }
        return;
    }
    int first_l=cap[first].left, first_r=cap[first].right, last_l=cap[last].left, last_r=cap[last].right;
    if(first!=first_l){
        int team=first_r/sq;
        for(j=first_l; j<=first_r; ++j) check[val[j]][team]=false;
        for(j=first_l; j<=first_r; ++j) {
            if(j>=first) val[j]+=task_val;
            check[val[j]][team]=true;
        }
        first=first/sq+2;
    }
    else first=first/sq+1;
    if(last!=last_r){
        int team=last_r/sq;
        for(j=last_l; j<=last_r; ++j) check[val[j]][team]=false;
        for(j=last_l; j<=last_r; ++j) {
            if(j<=last) val[j]+=task_val;
            check[val[j]][team]=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;
}
int read(){
    ++k;
    int nr=0;
    while(c[k]!='\n' && c[k]!=' ') {nr=nr*10+(c[k]-'0'); ++k;}
    return nr;
}