Cod sursa(job #3145326)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 14 august 2023 21:05:00
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <stdio.h>
#include <bitset>
#include <vector>
#include <cmath>
#define ORIGIN 1

struct elem {
   int start, end;
   int val;
};

struct valori {
   int nod, val = 0;
};

const int MAX = 100'002;
const int MAXS = 1'000'002;
const int sizeBucket = 317;

std::bitset<MAXS> bitBucket[MAX / sizeBucket];
int bucket[MAX / sizeBucket];
std::vector<int> adj[MAX];
std::bitset<MAX> ok;
elem info[MAX];
valori v[MAX];
int n, q;
int end;
int poz;


void makeOrdin(int nod = ORIGIN) {
   ok[nod] = 1;
   v[poz].nod = nod;
   info[nod].start = poz++;

   for(const int& x : adj[nod])
      if(!ok[x])
         makeOrdin(x);
   info[nod].end = poz - 1;
}

void update(int nod, int s) {
   int noStart = info[nod].start / sizeBucket;
   int valStart = info[nod].start % sizeBucket;
   
   int noEnd = info[nod].end / sizeBucket;
   int valEnd = info[nod].end % sizeBucket;

   if(noStart == noEnd) {
      int incepe = noStart * sizeBucket;

      bitBucket[noStart] = 0;
      for(int i = 0; i < valStart; i++) {
         v[incepe + i].val += bucket[noStart];
         bitBucket[noStart][v[incepe + i].val] = true;
      }

      for(int i = valStart; i <= valEnd; i++) {
         v[incepe + i].val += bucket[noStart] + s;
         bitBucket[noStart][v[incepe + i].val] = true;
      }

      for(int i = valEnd + 1; i < sizeBucket; i++) {
         v[incepe + i].val += bucket[noEnd];
         bitBucket[noEnd][v[incepe + i].val] = true;
      }
   } else {
      if(valStart != 0) {
         int incepe = noStart * sizeBucket;

         bitBucket[noStart] = 0;
         for(int i = 0; i < valStart; i++) {
            v[incepe + i].val += bucket[noStart];
            bitBucket[noStart][v[incepe + i].val] = true;
         }

         for(int i = valStart; i < sizeBucket; i++) {
            v[incepe + i].val += bucket[noStart] + s;
            bitBucket[noStart][v[incepe + i].val] = true;
         }
         noStart++;
      }

      if(valEnd == sizeBucket - 1)
         ++noEnd;
      else {
         int incepe = noEnd * sizeBucket;

         bitBucket[noEnd] = 0;
         for(int i = 0; i <= valEnd; i++) {
            v[incepe + i].val += bucket[noEnd] + s;
            bitBucket[noEnd][v[incepe + i].val] = true;
         }

         for(int i = valEnd + 1; i < sizeBucket; i++) {
            v[incepe + i].val += bucket[noEnd];
            bitBucket[noEnd][v[incepe + i].val] = true;
         }
      }

      for(int i = noStart; i < noEnd; i++) {
         bucket[noStart] += s;
         bitBucket[noStart] <<= s;
      }
   }
}

int query(int s) {
   int no = 0;
   while(no <= end && !bitBucket[no][s]) 
      ++no;

   if(no > end)
      return -1;
   else {
      int incepe = no * sizeBucket;
      int i = 0;
      while(i < sizeBucket && v[incepe + i].val != s)
         ++i;

      return v[incepe + i].nod;
   }
}

int main()
{
   freopen("arbore.in", "r", stdin);
   freopen("arbore.out", "w", stdout);

   scanf("%d %d", &n, &q);

   int end = n / sizeBucket + 3;
    for(int x, y, i = 1; i < n; i++){
      scanf("%d %d", &x, &y);
      adj[x].push_back(y);
      adj[y].push_back(x);
   }

   makeOrdin();

   while(q--) {
      int type, nod, s;
      scanf("%d", &type);

      if(type == 1) {
         scanf("%d %d", &nod, &s);
         update(nod, s);
      } else {
         scanf("%d", &s);
         int ans = query(s);
         printf("%d\n", ans);
      }
   }
   return 0;
}