Cod sursa(job #3200424)

Utilizator Cazacu2006RazvanRazvan Cazacu Cazacu2006Razvan Data 4 februarie 2024 17:36:18
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <fstream>
#include <unordered_map>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
int n,q,first[100001],last[100001],k,v[300001],valori[300001],L,nrb,S[401],c;
vector <int> A[100001];
unordered_map <int,int> fr[400];
int stb(int bucket)
{
 return (bucket-1)*L;
}
int drb(int bucket)
{
    return min(2*n-1,bucket*L-1);
}
int indb(int nr)
{
    return nr/L + (nr%L!=0);
}
void dfs(int nod)
{
    v[++k]=nod;
    first[nod]=k;
    for(auto i:A[nod])
    {
        dfs(i);
    }
    v[++k]=nod;
    last[nod]=k;
}
void update(int st,int dr,int val)
{
    int bst=indb(st);
    int bdr=indb(dr);

    int lmax=drb(bst);
    for(int i=st;i<=min(lmax,dr);i++)
    {
        fr[bst][valori[i]]--;
        if(fr[bst][valori[i]]<=0)
           {
               fr[bst].erase(valori[i]);
           }

        valori[i]+=val;
        fr[bst][valori[i]]++;

    }
    if(bst!=bdr)
    {

         for(int i=bst+1;i<bdr;i++)
         {
             S[i]+=val;
         }
         int lmin=stb(bdr);
         for(int i=lmin;i<=dr;i++)
         {
             fr[bst][valori[i]]--;
           if(fr[bst][valori[i]]<=0)
           {
               fr[bst].erase(valori[i]);
           }
        valori[i]+=val;
         fr[bdr][valori[i]]++;

         }
    }



}
int query(int val)
{
    for(int p=1;p<=nrb;p++)
    {

        if(fr[p].find(val-S[p])!=fr[p].end())
        {
            int st=stb(p);
            int dr=drb(p);
            for(int i=st;i<=dr;i++)
            {
                if(valori[i]+S[p]==val)
                    return v[i];
            }
        }
    }
    return -1;
}
int main()
{
    fin>>n>>q;
    for(int i=1;i<n;i++)
    {
        int x,y;
        fin>>x>>y;
        A[x].push_back(y);
    }
    dfs(1);
    L=sqrt((2*n+1));
    nrb=(2*n+1)/L+ ((2*n+1)%L!=0);


    for(int i=1;i<=nrb;i++)
    {
        int st=stb(i);
        int dr=drb(i);

        for(st;st<=dr;st++)
         fr[i][0]++;
    }
    for(int i=1;i<=q;i++)
    {
      fin>>c;
      if(c==1)
      {
          int x,y;
          fin>>x>>y;
          update(first[x],last[x],y);
      }
      else
      {
          int x;
          fin>>x;
        fout<<query(x)<<"\n";

      }
    }

    return 0;
}