Pagini recente » Cod sursa (job #609708) | Cod sursa (job #274577) | Cod sursa (job #2852475) | Cod sursa (job #2882058) | Cod sursa (job #3196214)
#include <fstream>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <map>
#include <cmath>
using namespace std;
ifstream fin ("arbore.in");
ofstream fout("arbore.out");
int n,m,x,T,y,i,Q,k,p,s,rad,nrb;
int V[200003];///suma adaugata manual la numerele din bucket-urile capetelor
int S[603];/// suma pe bucket-urile intermediare
int E[200003],first[100003],last[100003];/// reprezentarea euler
vector <int> L[100003];
unordered_map <int,int> F[603];///frecventa numerelor din bucket-uri
inline int bucket(int x){ return x/rad+(x%rad!=0);}///bucketul in care se afla
inline int bucket_start(int x){ return (x-1)*rad+1;}///bucketul care urmeaza
void dfs(int x,int t)
{
first[x]=++k;
E[k]=x;
for(auto j:L[x])
if(j!=t)
dfs(j,x);
last[x]=++k;
E[k]=x;
}
void update(int st,int dr,int val)
{
int st1=bucket(st);
int dr1=bucket(dr);
if(st1==dr1)///daca sunt intr-un singur bucket
{
for(int j=st;j<=dr;j++)
{
F[st1][V[j]]--;///scad frecventa numarului curent
if(F[st1][V[j]]<=0)
F[st1].erase(V[j]);
V[j]+=val;///adaug valoarea
F[st1][V[j]]++;///updatez frecventa noua
}
return;
}
for(int j=st;j<bucket_start(st1+1);j++)///updatam bucket-ul capatului stang de la st pana la inceputul bucketului urmator (exclusiv)
{
F[st1][V[j]]--;
if(F[st1][V[j]]<=0)
F[st1].erase(V[j]);
V[j]+=val;
F[st1][V[j]]++;
}
for(int j=st1+1;j<dr1;j++)///bucket-urile intermediare sunt updatate cu s
S[j]+=val;
for(int j=bucket_start(dr1);j<=dr;j++)///updatam bucket-ul capatului drept de la inceputul bucketului pana la dr
{
F[dr1][V[j]]--;
if(F[dr1][V[j]]<=0)
F[dr1].erase(V[j]);
V[j]+=val;
F[dr1][V[j]]++;
}
}
int query(int val)
{
for(int j=1;j<=nrb;j++)///cautam in bucketuri
if(F[j].find(val-S[j])!=F[j].end())///verificam daca exista valoarea ceruta in bucketul respectiv (valoarea ceruta = V[l]+S[l] asa ca cautam valoare-S[l]=V[l])
{
for(int l=bucket_start(j);l<bucket_start(j+1);l++)///cautam in bucket pozitia numarului
if(V[l]+S[j]==val)
return E[l];///E retine valoarea fiecarui indice in reprezentarea euler
}
return -1;
}
int main()
{
fin>>n>>m;
for(i=1;i<n;i++)
{
fin>>x>>y;
L[x].push_back(y);
L[y].push_back(x);
}
dfs(1,0);
rad=sqrt(k);///radicalul
nrb=k/rad+(k%rad!=0);///nr bucket-uri
for(i=1;i<=k;i++)
F[bucket(i)][0]++;///initializam frecventa tuturor numerelor cu 1 la 0 caci toate sunt goale
for(i=1;i<=m;i++)
{
fin>>T;
if(T==1)
{
fin>>p>>s;
update(first[p],last[p],s);///adaugam s la toate numerele din reprezentarea euler in intervalul first[p]->last[p]
}
else
{
fin>>s;
fout<<query(s)<<"\n";///cautam s
}
}
return 0;
}