Cod sursa(job #1567586)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 13 ianuarie 2016 16:11:39
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.26 kb
#include <cstdio>
#include <cstring>
#include <bitset>

#define MaxN 100050
#define MaxS 1000050
#define BUCKET 500
#define MaxBuckets 410
#define NIL -1

using namespace std;

struct Edge {
   int v;
   int next;
};

Edge l[2 * (MaxN - 1)];
int adj[MaxN];
int sum[2 * MaxN + BUCKET];

bitset <MaxS + 2> H[MaxBuckets];
int lazy[MaxBuckets];
int euler[2 * MaxN];
pair <int, int> node2Euler[MaxN];
int ptr;

static inline void addEdge(const int &u, const int &v, const int &pos) {
   l[pos].v =v;
   l[pos].next = adj[u];
   adj[u] = pos;
}

void DFS(int u, int parent) {
   euler[ptr] = u;
   node2Euler[u].first = ptr++;
   for (int i = adj[u]; i != NIL; i = l[i].next) {
      if (l[i].v != parent) {
         DFS(l[i].v, u);
      }
   }
   euler[ptr] = u;
   node2Euler[u].second = ptr++;
}

int main() {
   freopen("arbore.in", "rb", stdin);
   freopen("arbore.out", "wb", stdout);
   int N, Q;
   int u, v;
   int opType, add;
   int numBuckets;

   scanf("%d%d", &N, &Q);
   memset(adj, NIL, 4 * N);
   for (int i = 1; i < N; i++) {
      scanf("%d%d", &u, &v);
      addEdge(u - 1, v - 1, 2 * i - 2);
      addEdge(v - 1, u - 1, 2 * i - 1);
   }

   DFS(0, -1);
   numBuckets = -1;
   for (int i = 0; i < ptr; i++) {
      numBuckets += (i == i / BUCKET * BUCKET);
      H[numBuckets][0] = 1;
   }

   while (ptr != ptr / BUCKET * BUCKET) {
      sum[ptr++] = MaxS + 1;
   }

   return 0;

   while (Q--) {
      scanf("%d", &opType);
      if (opType == 1) {
         scanf("%d%d", &u, &add); u--;

         int bucket = node2Euler[u].first / BUCKET;
         int startBucket = bucket * BUCKET;
         int endBucket = startBucket + BUCKET;

         for (int i = startBucket; i < endBucket; i++) {
            H[bucket][sum[i]] = 0;
         }
         for (int i = node2Euler[u].first; (i < endBucket) && (i <= node2Euler[u].second); i++) {
            sum[i] += add;
         }
         for (int i = startBucket; i < endBucket; i++) {
            H[bucket][sum[i]] = 1;
         }

         if (node2Euler[u].second / BUCKET != bucket) {
            int fnBucket = node2Euler[u].second / BUCKET;
            for (int i = bucket + 1; i < fnBucket; i++) {
               lazy[i] += add;
            }
            startBucket = fnBucket * BUCKET;
            endBucket = startBucket + BUCKET;
            for (int i = startBucket; i < endBucket; i++) {
               H[fnBucket][sum[i]] = 0;
            }
            for (int i = startBucket; i <= node2Euler[u].second; i++) {
               sum[i] += add;
            }
            for (int i = startBucket; i < endBucket; i++) {
               H[fnBucket][sum[i]] = 1;
            }
         }
      } else {
         scanf("%d", &add);

         int bucket = 0;
         while (bucket <= numBuckets && (add - lazy[bucket] < 0 || !H[bucket][add - lazy[bucket]])) {
            bucket++;
         }
         if (bucket <= numBuckets) {
            add -= lazy[bucket];
            bucket *= BUCKET;
            while (sum[bucket] != add) {
               bucket++;
            }
            printf("%d\n", 1 + euler[bucket]);
         } else {
            puts("-1");
         }
      }
   }
   fclose(stdin);
   fclose(stdout);
   return 0;
}