Cod sursa(job #2217352)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 30 iunie 2018 03:53:55
Problema Stergeri Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.02 kb
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define mp make_pair
#define CHECK(x) if(!(x)) return false;
#define SKIP(x) if((x)) continue;
typedef pair<int, int> pii;

#ifdef INFOARENA
#define ProblemName "stergeri"
#endif

#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif

const int MAXBUF = 30000000;
char parseBuf[MAXBUF];
char *head;
bool isDigit[255];

void parseInit() {
  int a = fread(parseBuf, 1, MAXBUF, stdin);
  parseBuf[a] = 0;
  head = parseBuf;
  memset(isDigit, 0, sizeof isDigit);
  for (int i = '0'; i <= '9'; ++i)
    isDigit[i] = true;
}

int nextInt() {
  int ans = 0;
  for (; !isDigit[*head]; ++head);
  for (; isDigit[*head]; ++head)
    ans = ans * 10 + (*head) - '0';
  return ans;
}

struct node {
private:
  node* L;
  node* R;
public:
  int x, y;
  int size;
  pii lft, rft;
  node(int x, pii Lft, pii Rft) {
    this->x = x;
    L = R = NULL;
    size = Rft.second - Rft.first + Lft.second - Lft.first + 1;
    y = rand();
    lft = Lft, rft = Rft;
  }
  node *&left() {
    if (L == NULL && lft.first < lft.second) {
      int mid = lft.first + (lft.second - lft.first) / 2;
      L = new node(mid, mp(lft.first, mid), mp(mid + 1, lft.second));
      lft.first = lft.second = -1;
    }
    return L;
  }
  node *&right() {
    if (R == NULL && rft.first < rft.second) {
      int mid = rft.first + (rft.second - rft.first) / 2;
      R = new node(mid, mp(rft.first, mid), mp(mid + 1, rft.second));
      rft.first = rft.second = -1;
    }
    return R;
  }

  ~node() {
    if (L != NULL) delete L;
    if (R != NULL) delete R;
  }
};

inline int size(node *p) {
  return p ? p->size : 0;
}

void recalc(node* p) {
  if (!p) return;
  p->size = size(p->left()) + size(p->right()) + 1;
}

void tsplit(node *root, int k, node **l, node **r) {
  if (root == NULL) {
    *l = NULL;
    *r = NULL;
    return;
  }
  if (k <= size(root->left())) {
    tsplit(root->left(), k, l, &root->left());
    *r = root;
  }
  else {
    tsplit(root->right(), k - size(root->left()) - 1, &root->right(), r);
    *l = root;
  }
  recalc(root);
}

node *tmerge(node *l, node *r) {
  if (l == NULL) return r;
  if (r == NULL) return l;
  if (l->y < r->y) {
    r->left() = tmerge(l, r->left());
    recalc(r);
    return r;
  }
  else {
    l->right() = tmerge(l->right(), r);
    recalc(l);
    return l;
  }
}

node *tadd(node *root, node *n, int k) {
  if (root == NULL) return n;
  if (n->y > root->y) {
    node *r, *l;
    tsplit(root, k - 1, &l, &r);
    n->left() = l;
    n->right() = r;
    recalc(n);
    return n;
  }
  if (k <= size(root->left()) + 1)
    root->left() = tadd(root->left(), n, k);
  else
    root->right() = tadd(root->right(), n, k - size(root->left()) - 1);
  recalc(root);
  return root;
}

node *tremove(node *root, int k) {

  if (root == NULL)
    return root;

  if (size(root->left()) + 1 == k) {
    node *bak = root;
    root = tmerge(root->left(), root->right());
    delete bak;
    return root;
  }

  if (k <= size(root->left()))
    root->left() = tremove(root->left(), k);
  else root->right() = tremove(root->right(), k - size(root->left()) - 1);

  recalc(root);
  return root;
}

node *tkthelement(node *root, int k) {
  if (root == NULL)
    return NULL;
  if (size(root->left()) + 1 == k)
    return root;
  if (k <= size(root->left()))
    return tkthelement(root->left(), k);
  return tkthelement(root->right(), k - size(root->left()) - 1);
}


int main() {
  assert(freopen(InFile, "r", stdin));
  assert(freopen(OuFile, "w", stdout));
  parseInit();
  int N = nextInt(), M = nextInt(), K = nextInt();
  int mid = 1 + N / 2;
  node *T = new node(mid, mp(1, mid), mp(mid + 1, N + 1));
  while (M--) {
    int li = nextInt(), ri = nextInt();
    node *l, *mid, *r;
    tsplit(T, ri, &mid, &r);
    tsplit(mid, li - 1, &l, &mid);
    T = tmerge(l, r);
    delete mid;
  }
  printf("%d\n", tkthelement(T, K)->x);
  return 0;
}