Cod sursa(job #2217354)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 30 iunie 2018 04:02:39
Problema Stergeri Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.57 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 = 5000000;
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;
  void init(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();
  node *&right();
  friend void uninit(node*);
};

set<node*> nodeCache;

inline node *fetchNode(int x, pii Lft, pii Rft) {
  if (nodeCache.empty())
    nodeCache.insert(new node());
  node *n = *nodeCache.begin();
  nodeCache.erase(nodeCache.begin());
  n->init(x, Lft, Rft);
  return n;
}

void uninit(node *root) {
  if (root->L != NULL) uninit(root->L);
  if (root->R != NULL) uninit(root->R);
  nodeCache.insert(root);
}

node *&node::left() {
  if (L == NULL && lft.first < lft.second) {
    int mid = lft.first + (lft.second - lft.first) / 2;
    L = fetchNode(mid, mp(lft.first, mid), mp(mid + 1, lft.second));
    lft.first = lft.second = -1;
  }
  return L;
}
node *&node::right() {
  if (R == NULL && rft.first < rft.second) {
    int mid = rft.first + (rft.second - rft.first) / 2;
    R = fetchNode(mid, mp(rft.first, mid), mp(mid + 1, rft.second));
    rft.first = rft.second = -1;
  }
  return 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 *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 = fetchNode(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);
    uninit(mid);
  }
  printf("%d\n", tkthelement(T, K)->x);
  return 0;
}