Cod sursa(job #3241770)

Utilizator Dia3141Costea Diana Stefania Dia3141 Data 3 septembrie 2024 18:28:03
Problema Arbore Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <fstream>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>
#define nmax 100100
using namespace std;
ifstream cin("arbore.in");
ofstream cout("arbore.out");
int n,m,q,x,y,poz,nrb,r,a[nmax],first[nmax],last[nmax],b[320],add[nmax];
vector<int>v[nmax];
unordered_map<int,int>fr[320]; /// frecventa pentru sumele care nu le fac in bucket
void dfs(int nod){
    a[++poz]=nod;
    first[nod]=poz;
    for(auto i: v[nod])
        if(first[i]==0&&i!=1)
            dfs(i);
    last[nod]=poz;
}
void update(int x,int y,int s){
    int b1=x/r,b2=y/r;
    for(int i=b1;i<=b2;i++){
        int st=i*r,dr=min((i+1)*r-1,n-1);
        if(st>=x&&dr<=y){
            b[i]+=s;
            continue;
        }
        if(st<x)
            st=x;
        if(dr>y)
            dr=y;
        for(int j=st;j<=dr;j++){
            fr[i][add[j]]--;
            if(fr[i][add[j]]<=0)
                fr[i].erase(add[j]);
            add[j]+=s;
            fr[i][add[j]]++;
        }
    }
}
int query(int s){
    for(int i=0;i<nrb;i++)
        if(fr[i].find(s-b[i])!=fr[i].end()){
            int st=i*r,dr=min((i+1)*r-1,n-1);
            for(int j=st;j<=dr;j++)
                if(add[j]+b[i]==s)
                    return a[j];
        }
    return -1;
}
int main()
{
    cin>>n>>m;
    r=sqrt(n);
    nrb=n/r;
    for(int i=1;i<n;i++){
        cin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    poz=-1;
    dfs(1);
    for(int i=0;i<n;i++)
        fr[i/r][0]++;
    while(m--){
        cin>>q>>x;
        if(q==1){
            cin>>y;
            update(first[x],last[x],y);
        }else
            cout<<query(x)<<'\n';
    }
}
/// liniarizarea arborelui + square root decomposition