Pagini recente » Cod sursa (job #593635) | Cod sursa (job #212514) | Cod sursa (job #2066941) | Cod sursa (job #946494) | Cod sursa (job #1951941)
#include <fstream>
#include <vector>
#include <cmath>
#define sqnMax 340
#define nMax 100001
#define sMax 1000001
#define pb push_back
using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
int n, nrQuery, sqn, nrBlocks, nrE;
int first[nMax], which[nMax], last[nMax], sumNode[nMax], addBlock[sqnMax];
bool have[sqnMax][sMax];
vector<int> G[nMax];
void depthFirstSearch(int node, int tata)
{
first[node]=++nrE;
which[nrE]=node;
for(vector<int>::iterator it=G[node].begin(); it!=G[node].end(); it++)
if(*it!=tata)
depthFirstSearch(*it, node);
last[node]=nrE;
}
int getBlock(int ind)
{
if(ind%sqn==0)
return ind/sqn;
return (ind/sqn)+1;
}
void upDateBlock(int block)
{
for(int i=(block-1)*sqn+1; i<=min(block*sqn, n); i++)
have[block][sumNode[i]]=1;
}
void upDate(int node, int val)
{
int block1=getBlock(first[node]), block2=getBlock(last[node]);
for(int i=first[node]; getBlock(i)==block1 && i<=last[node]; i++)
{
sumNode[i]+=val;
have[block1][sumNode[i]-val]=0;
}
upDateBlock(block1);
for(int i=block1+1; i<block2; i++)
addBlock[i]+=val;
if(block1!=block2)
{
for(int i=(block2-1)*sqn+1; i<=last[node]; i++)
{
sumNode[i]+=val;
have[block2][sumNode[i]-val]=0;
}
upDateBlock(block2);
}
}
int getNode(int block, int sum)
{
for(int i=(block-1)*sqn+1; i<=min(block*sqn, n); i++)
if(sumNode[i]==sum)
return which[i];
}
int query(int sum)
{
for(int i=1; i<=nrBlocks; i++)
if(sum-addBlock[i]>=0 && have[i][sum-addBlock[i]])
return getNode(i, sum-addBlock[i]);
return -1;
}
int main()
{
int op, a, b;
fin>>n>>nrQuery;
for(int i=1; i<n; i++)
{
fin>>a>>b;
G[a].pb(b);
G[b].pb(a);
}
depthFirstSearch(1, 0);
sqn=sqrt(n);
nrBlocks=n/sqn;
if(n%sqn!=0)
nrBlocks++;
for(int i=1; i<=nrQuery; i++)
{
fin>>op;
if(op==1)
{
fin>>a>>b;
upDate(a, b);
continue;
}
fin>>a;
fout<<query(a)<<'\n';
}
}