Cod sursa(job #2018489)

Utilizator LucianTLucian Trepteanu LucianT Data 5 septembrie 2017 00:29:59
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <bits/stdc++.h>
using namespace std;
const int maxN=1e5+4;

int n,q,timp;
int sqroot,BLOCKS;
vector<int> v[maxN];
int start[2*maxN],stop[2*maxN];
int euler[2*maxN];
int value[2*maxN];
int add[maxN];
bitset<maxN> vis[500];

void dfs(int nod,int tata)
{
    start[nod]=++timp;
    euler[timp]=nod;

    for(auto it:v[nod])
        if(it!=tata)
            dfs(it,nod);

    stop[nod]=timp;
}

void updatebit(int idx)
{
    int lef=(idx-1)*sqroot+1;
    int rig=min(timp,idx*sqroot);

    for(int i=lef;i<=rig;i++)
        vis[idx][value[i]]=true;
}
void brut(int idx,int st,int dr,int val)
{
    for(int i=st;i<=dr;i++){
        vis[idx][value[i]]=false;
        value[i]+=val;
    }
    updatebit(idx);
}

void update(int st,int dr,int val)
{
    int firstblock=(st-1)/sqroot+1;
    int lastblock=(dr-1)/sqroot+1;

    for(int i=firstblock+1;i<=lastblock-1;i++)
        add[i]+=val;

    if(firstblock==lastblock){
        for(int i=st;i<=dr;i++){
            vis[firstblock][value[i]]=false;
            value[i]+=val;
        }
        updatebit(firstblock);
        return;
    }
    int rig=min(timp,(firstblock)*sqroot);

    for(int i=st;i<=rig;i++){
        vis[firstblock][value[i]]=0;
        value[i]+=val;
    }

    int lef=(lastblock-1)*sqroot+1;

    for(int i=lef;i<=dr;i++){
        vis[lastblock][value[i]]=0;
        value[i]+=val;
    }

    updatebit(firstblock);
    updatebit(lastblock);
}
int query(int val)
{
    int bucket=0;
    for(int i=1;i<=BLOCKS;i++)
        if(val-add[i]>=0 && vis[i][val-add[i]]==true){
            bucket=i;
            break;
        }
    if(bucket==0)
        return -1;

    int pr=(bucket-1)*sqroot+1;
    int ul=min(timp,bucket*sqroot);
    for(int i=pr;i<=ul;i++)
        if(value[i]==val-add[bucket])
            return euler[i];

    return -1;
}

int main()
{
    freopen("arbore.in","r",stdin);
    freopen("arbore.out","w",stdout);

    scanf("%d %d",&n,&q);
    for(int i=1;i<n;i++){
        int x,y;
        scanf("%d %d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    dfs(1,0);
    sqroot=sqrt(1.0*n);

    for(int i=1;i<=n;i+=sqroot){
        vis[++BLOCKS][0]=true;
    }

    while(q--)
    {
        int op;
        scanf("%d",&op);
        if(op==1){
            int nod,val;
            scanf("%d %d",&nod,&val);
            update(start[nod],stop[nod],val);
        }
        else{
            int val;
            scanf("%d",&val);
            int res=query(val);
            printf("%d\n",res);
        }
    }

    return 0;
}