Cod sursa(job #3157357)

Utilizator SerbanCaroleSerban Carole SerbanCarole Data 15 octombrie 2023 13:57:50
Problema Arbore Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <fstream>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <bitset>
#define pb push_back
#define int long long
using namespace std;
ifstream cin("arbore.in");
ofstream cout("arbore.out");
using pii = pair<int,int>;
const int nmax = 1e5 + 3;
int e[nmax*2] , n , x , y , q , op , tin[nmax] , tout[nmax] , t , wo[nmax*2] , a[nmax*2] , bb, sz;
const int b = (int)sqrt(nmax*2)+1;
vector <int> g[nmax];
unordered_map<int,int>um[500];
int add[500];
void dfs(int x)
{
    tin[x] = ++t;
    e[t] = x;
    for(auto &it : g[x])
    {
        if(tin[it]) continue;
        dfs(it);
    }
    tout[x] = ++t;
    e[t] = x;
}
void prop(int &l , int &r , int &v)
{
    int lb = l/b;
    int rb = r/b;
    if(l/b==r/b)
    {
        for(int i = l ; i <= r ; ++i)
        {
            um[lb][a[i]]--;
            a[i]+=v;
            um[lb][a[i]]++;
        }
    }
    else
    {
        for(int i = lb+1 ; i < rb ; ++i) add[i]+=v;
        for(int i = min((lb+1)*b-1,sz) ; i >= l ; --i)
        {
            um[lb][a[i]]--;
            a[i]+=v;
            um[lb][a[i]]++;
        }
        for(int i = max(b*rb,1LL) ; i <= r ; ++i)
        {
            um[rb][a[i]]--;
            a[i]+=v;
            um[rb][a[i]]++;
        }
    }
}
int check(int &v)
{
    for(int i = 0 ; i <= bb ; ++i)
    {
        if(um[i][v-add[i]])
        {
            int up = min(sz,(i+1)*b);
            for(int j = i*b ; j < up ; ++j)
            {
                if(a[j]+add[i]==v)
                {
                    return e[j];
                }
            }
        }
    }
    return -1;
}
signed main()
{
    cin >> n >> q;
    for(int i = 1 ; i < n ; i++)
    {
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(1);
    sz = n*2;
    bb = 0;
    for(int i = 1 ; i*b <= sz ; ++i)
    {
        wo[i*b]++;
        bb = i*b;
    }
    for(int i = 1 ; i <= sz ; ++i) wo[i] += wo[i-1];
    for(int i = 1 ; i <= sz ; ++i)
    {
        um[wo[i]][a[i]]++;
    }
    while(q--)
    {
        cin >> op;
        if(op==1)
        {
            cin >> x >> y;
            prop(tin[x],tout[x],y);
        }
        else
        {
            cin >> x;
            cout << check(x) << '\n';
        }
    }
    return 0;
}