Cod sursa(job #1784473)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 20 octombrie 2016 03:43:55
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.68 kb
// Lisp indent is good for your health
#include <bits/stdc++.h>
using namespace std;

const int INF = 0x7FFFFFFF;

const int BUFF_SIZE = (1 << 17);

FILE *fin, *fout;
int bp = BUFF_SIZE - 1;
char buff[BUFF_SIZE];

inline void next_char() {
  if (++bp == BUFF_SIZE) {
    fread(buff, 1, BUFF_SIZE, fin);
    bp = 0;
  }
}

inline char get_char() {
  while (isalnum(buff[bp]) == 0)
    next_char();
  char ch = buff[bp];
  next_char();
  return ch;
}

inline int get_num() {
  int num = 0;
  while (isdigit(buff[bp]) == 0)
    next_char();
  while (isdigit(buff[bp])) {
    num = num * 10 + buff[bp] - '0';
    next_char();
  }
  return num;
}

struct T {
    int val, siz, pr;
    bool rev;
    T *st, *dr; } nil {0, 0, -1, false, 0x00, 0x00};

void reset(T *a) {
    a->siz = a->st->siz + a->dr->siz + 1; }

void prop(T *a) {
    if(a->rev) {
        a->rev = 0;
        a->st->rev^= 1;
        a->dr->rev^= 1;
        swap(a->st, a->dr); } }

T* join(T *a, T *b) {
    if(a == &nil) return b;
    if(b == &nil) return a;

    prop(a);
    prop(b);

    if(a->pr > b->pr) {
        a->dr = join(a->dr, b);
        reset(a);
        return a; }
    else {
        b->st = join(a, b->st);
        reset(b);
        return b; } }

T* join3(T *a, T *b, T *c) {
    return join(a, join(b, c)); }

pair<T*, T*> split(T *nod, int pos) {
    if(nod == &nil) return make_pair(&nil, &nil);

    prop(nod);

    if(nod->st->siz == pos) {
        T *tmp = nod->st;
        nod->st = &nil;
        reset(nod);
        return make_pair(tmp, nod); }
    if(nod->st->siz > pos) {
        auto tmp = split(nod->st, pos);
        nod->st = tmp.second;
        reset(nod);
        return make_pair(tmp.first, nod); }
    if(nod->st->siz < pos) {
        auto tmp = split(nod->dr, pos-nod->st->siz-1);
        nod->dr = tmp.first;
        reset(nod);
        return make_pair(nod, tmp.second); } }

tuple<T*, T*, T*> split3(T* nod, int x, int y) {
    auto a = split(nod, y);
    auto b = split(a.first, x);
    return make_tuple(b.first, b.second, a.second); }

T* reverse(T *nod, int x, int y) {
    auto tp = split3(nod, x, y);
    get<1>(tp)->rev^= 1;
    return join3(get<0>(tp), get<1>(tp), get<2>(tp)); }

T* insert(T *nod, int pos, int val) {
    auto pr = split(nod, pos);
    return join3(pr.first, new T {val, 1, rand(), false, &nil, &nil}, pr.second); }

T* remove(T *nod, int x, int y) {
    auto tp = split3(nod, x, y);
    return join(get<0>(tp), get<2>(tp)); }

T *kth(T *nod, int pos) {
    prop(nod);

    if(nod->st->siz == pos) return nod;
    if(nod->st->siz > pos) return kth(nod->st, pos);
    if(nod->st->siz < pos) return kth(nod->dr, pos-nod->st->siz-1); }

void dfs(T *nod) {
    if(nod == &nil) return;
    prop(nod);

    dfs(nod->st);
    if(nod->val > 0)
        printf("%d ", nod->val);
    dfs(nod->dr); }

int main(void) {
    freopen("secv8.in",  "r", stdin); fin = stdin;
    freopen("secv8.out", "w", stdout);
    int m, val, pos, x, y, junk;
    char op;
    T *root;

    root = &nil;
    srand(time(NULL));

    m = get_num(), junk = get_num();
    while(m--) {
        while(!isalpha(op = get_char()));

        switch(op) {
            case 'I': {
                pos = get_num(), val = get_num();
                root = insert(root, pos-1, val);
                break; }
            case 'R': {
                x = get_num(), y = get_num();
                root = reverse(root, x-1, y);
                break; }
            case 'A': {
                pos = get_num();
                printf("%d\n", kth(root, pos-1)->val);
                break; }
            case 'D': {
                x = get_num(), y = get_num();
                root = remove(root, x-1, y);
                break; } } }

    dfs(root);
    printf("\n");

    return 0; }