Pagini recente » Cod sursa (job #1427686) | Cod sursa (job #700838) | Cod sursa (job #2096195) | Cod sursa (job #2555020) | Cod sursa (job #933328)
Cod sursa(job #933328)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;
#define ChunkMax 350
#define Nmax 100010
#define ValMax 1000010
#define forit(it, v) for(typeof((v).begin()) it = (v).begin(); it != (v).end(); ++ it)
#define pb push_back
//Impart sirul de dupa liniarizare in bucati de sqrt(N) (chunk)
//Calculez marimea unui chunk si ce interval contine
//Tin ChunkSums[i][j] - 1 daca suma j apare in al i-lea chunk
//ChunkTotal[i] - cat am adunat la tot intervalul asociat chunk-ului i
//Cand fac update, daca tot intervalul chunk-ului e cuprins in intervalul de update, adaug la ChunkTotal
//Altfel refac sumele, adaugat la fiecare element dintr-un chunk ChunkTotal si, daca se poate, valoarea de update
//La query imi caut un chunk la care daca scad din suma de query ChunkTotal, sa fie o suma care apare in acel chunk
//Caut pozitia unde apare acea suma si returnez ce apare pe acea pozitie in liniarizare
int N, M, K, Type, Pos, Sum, X, Y, First[Nmax], Last[Nmax], Lin[Nmax];
int V[Nmax], ChunkTotal[ChunkMax], NrChunks, ChunkSize;
int LeftChunk[ChunkMax], RightChunk[ChunkMax];
bitset<ValMax> ChunkSums[ChunkMax];
vector<int> G[Nmax];
void DFS(int Node)
{
First[Node] = ++ K;
Lin[K] = Node;
forit(it, G[Node])
if(!First[*it])
DFS(*it);
Last[Node] = K;
}
void Build_Chunks()
{
for(ChunkSize = 1; ChunkSize * ChunkSize <= N; ++ ChunkSize);
ChunkSize --;
for(int i = 1; i <= N; )
{
NrChunks ++;
LeftChunk[NrChunks] = i;
RightChunk[NrChunks] = min(i + ChunkSize - 1, N);
ChunkSums[NrChunks][0] = 1;
i += ChunkSize;
}
}
void Update(int Left, int Right, int Sum)
{
for(int i = 1; i <= NrChunks; ++ i)
{
if(LeftChunk[i] > Right) break;
if(RightChunk[i] < Left) continue;
if(Left <= LeftChunk[i] && RightChunk[i] <= Right)
{
ChunkTotal[i] += Sum;
continue;
}
for(int j = LeftChunk[i]; j <= RightChunk[i]; ++ j)
{
ChunkSums[i][V[j]] = 0;
V[j] += ChunkTotal[i];
if(Left <= j && j <= Right) V[j] += Sum;
}
ChunkTotal[i] = 0;
for(int j = LeftChunk[i]; j <= RightChunk[i]; ++ j)
ChunkSums[i][V[j]] = 1;
}
}
int Query(int Sum)
{
for(int i = 1; i <= NrChunks; ++ i)
{
if(Sum < ChunkTotal[i]) continue;
if(ChunkSums[i][Sum - ChunkTotal[i]])
for(int j = LeftChunk[i]; j <= RightChunk[i]; ++ j)
if(V[j] == Sum - ChunkTotal[i])
return Lin[j];
}
return -1;
}
int main()
{
freopen("arbore.in", "r", stdin);
freopen("arbore.out", "w", stdout);
int i, j;
scanf("%i %i", &N, &M);
for(i = 1; i < N; ++ i)
{
scanf("%i %i", &X, &Y);
G[X].pb(Y);
G[Y].pb(X);
}
DFS(1);
Build_Chunks();
for(i = 1; i <= M; ++ i)
{
scanf("%i", &Type);
if(Type == 1)
{
scanf("%i %i", &Pos, &Sum);
Update(First[Pos], Last[Pos], Sum);
}else
{
scanf("%i", &Sum);
printf("%i\n", Query(Sum));
}
}
return 0;
}