Cod sursa(job #2472175)

Utilizator borcanirobertBorcani Robert borcanirobert Data 12 octombrie 2019 10:03:38
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.69 kb
#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);
    }

    a.push_back(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(n, 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;
}