Cod sursa(job #1505118)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 18 octombrie 2015 19:46:01
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.37 kb
#include <cstdio>
#include <cstdlib>
#include <bitset>
#define MAGIC 330
#define MAXN 100000
#define CEL 304
#define MAXV 1000000
std::bitset <MAXV+2> s[CEL+1];
int k, m, maxlin, viz[MAXN+1], v[MAGIC*CEL+1], st[MAXN+1], dr[MAXN+1], next[2*MAXN-1], val[2*MAXN-1], lista[MAXN+1], g[MAXN+1], sum[CEL+1];
inline void adauga(int x, int y){
    m++;
    val[m]=y;
    next[m]=lista[x];
    lista[x]=m;
}
void dfs(int x){
    int p=lista[x];
    viz[x]=1;
    k++;
    v[k-1]=0;
    g[k-1]=x;
    st[x]=k-1;
    while(p){
        if(viz[val[p]]==0){
            dfs(val[p]);
        }
        p=next[p];
    }
    dr[x]=k-1;
}
inline void add(int l, int a, int b, int e){
    int i;
    for(i=a; i<=b; i++){
        s[l][v[l*MAGIC+i]]=0;
        v[l*MAGIC+i]+=e;
    }
    for(i=0; i<MAGIC; i++){
        s[l][v[l*MAGIC+i]]=1;
    }
}
inline void update(int a, int b, int e){
    int i;
    for(i=a/MAGIC-(a%MAGIC==0)+1; i<(b+1)/MAGIC; i++){
        sum[i]+=e;
    }
    if(a/MAGIC<b/MAGIC){
        if(a%MAGIC!=0){
            add(a/MAGIC, a%MAGIC, MAGIC-1, e);
        }
        if((b+1)%MAGIC!=0){
            add(b/MAGIC, 0, b%MAGIC, e);
        }
    }else{
        add(a/MAGIC, a%MAGIC, b%MAGIC, e);
    }
}
inline int find(int l, int x){
    for(int i=0; i<MAGIC; i++){
        if(v[l*MAGIC+i]==x){
            return g[l*MAGIC+i];
        }
    }
    return -1;
}
inline int query(int x){
    for(int i=0; i<=maxlin; i++){
        if((x-sum[i]>=0)&&(s[i][x-sum[i]])){
            return find(i, x-sum[i]);
        }
    }
    return -1;
}
int main(){
    int n, q, x, y, root, o, i;
    FILE *fin, *fout;
    fin=fopen("arbore.in", "r");
    fout=fopen("arbore.out", "w");
    fscanf(fin, "%d%d", &n, &q);
    for(i=1; i<n; i++){
        fscanf(fin, "%d%d", &x, &y);
        adauga(x, y);
        adauga(y, x);
    }
    root=1;
    dfs(root);
    maxlin=n/MAGIC;
    if(n%MAGIC!=0){
        for(i=n%MAGIC; i<MAGIC; i++){
            v[MAGIC*maxlin+i]=MAXV+1;
        }
    }
    for(i=0; i<=maxlin; i++){
        add(i, 0, MAGIC-1, 0);
    }
    for(; q; q--){
        fscanf(fin, "%d%d", &o, &x);
        if(o==1){
            fscanf(fin, "%d", &y);
            update(st[x], dr[x], y);
        }else{
            fprintf(fout, "%d\n", query(x));
        }
    }
    fclose(fin);
    fclose(fout);
    return 0;
}