Pagini recente » Cod sursa (job #708172) | Cod sursa (job #278682) | Cod sursa (job #2688668) | Cod sursa (job #1632234) | Cod sursa (job #2472198)
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
using namespace std;
ifstream fin("arbore.in");
ofstream fout("arbore.out");
using VI = vector<int>;
using VVI = vector<VI>;
using VB = vector<bool>;
const int VMAX = 1000002;
struct SqrtPart{
SqrtPart(int size)
: size{size}, add{0}
{}
int size;
int add;
bitset<VMAX> e;
};
int N, M;
VVI G;
VI A;
VI a;
VI first, last;
vector<SqrtPart> s;
int sqrtSize;
int n;
void ReadData();
void MakeArrayFromGraph();
void DFS(int node, int f);
void Update(int pos, int val);
void Update(int p1, int p2, int val);
void UpdatePart(SqrtPart& p, int start);
int Query(int val);
int main()
{
ReadData();
MakeArrayFromGraph();
int type, p, s;
while (M--)
{
fin >> type;
if (type == 1)
{
fin >> p >> s;
// Update(p, s);
}
else
{
fin >> s;
// fout << Query(s) << '\n';
}
}
fin.close();
fout.close();
return 0;
}
void ReadData()
{
fin >> N >> M;
G = VVI(N + 1);
first = last = VI(N + 1);
int x, y;
for (int i = 1; i < N; ++i)
{
fin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
}
void MakeArrayFromGraph()
{
DFS(1, 0);
n = static_cast<int>(a.size());
while (sqrtSize * sqrtSize < n)
++sqrtSize;
for (int i = 0; i < n; i += sqrtSize)
{
int sz = min(sqrtSize, n - i);
s.push_back(SqrtPart(sz));
}
A = VI(n);
}
void DFS(int node, int f)
{
a.push_back(node);
first[node] = static_cast<int>(a.size()) - 1;
for (const int& son : G[node])
{
if (son == f)
continue;
DFS(son, node);
}
last[node] = static_cast<int>(a.size()) - 1;
}
void Update(int pos, int val)
{
Update(first[pos], last[pos], val);
}
void Update(int p1, int p2, int val)
{
int p = p1 / sqrtSize;
for (int i = p1; i < min(min(n, p2 + 1), sqrtSize * (p + 1)); ++i)
{
s[p].e[A[i]] = false;
A[i] += val;
}
UpdatePart(s[p], p * sqrtSize);
/* cout << "Dupa Update: " << p1 << ' ' << p2 << ' ' << val << '\n';
for (int i = 0; i < n; ++i)
{
cout << A[i] + s[i / sqrtSize].add << ' ';
}
cout << '\n'; */
if (p2 / sqrtSize != p1 / sqrtSize)
{
p = p2 / sqrtSize;
for (int i = p2; i >= max(0, p * sqrtSize); --i)
{
s[p].e[A[i]] = false;
A[i] += val;
}
UpdatePart(s[p], p * sqrtSize);
}
/* cout << "Dupa Update: " << p1 << ' ' << p2 << ' ' << val << '\n';
for (int i = 0; i < n; ++i)
{
cout << A[i] + s[i / sqrtSize].add << ' ';
}
cout << '\n'; */
for (int part = p1 / sqrtSize + 1; part < p2 / sqrtSize; ++part)
s[part].add += val;
/* cout << "Dupa Update: " << p1 << ' ' << p2 << ' ' << val << '\n';
for (int i = 0; i < n; ++i)
{
cout << A[i] + s[i / sqrtSize].add << ' ';
}
cout << '\n';
cout << '\n'; */
}
void UpdatePart(SqrtPart& p, int start)
{
for (int i = start; i < start + sqrtSize && i < n; ++i)
p.e[A[i]] = true;
}
int Query(int val)
{
for (size_t part = 0; part < s.size(); ++part)
{
int v = val - s[part].add;
if (v >= 0 && !s[part].e[v])
continue;
for (int i = part * sqrtSize; i < (part + 1) * sqrtSize && i < n; ++i)
if (A[i] == v)
return a[i];
}
return -1;
}