Problem p00459 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int, int> P;
typedef std::pair<int, P> State;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1},
          dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

int N, M;

struct Node {
  int begin, end;
  Node *prev, *next;
};

// 0, 1, 2, 3, 4, 5, 6, 7, 8
// 1, 2, 3, 4, 5, 6, 7, 8, 9
// [6, 7, 8, 9], [4, 5], [1, 2, 3]
Node *update(Node *n, int index) {
  int size = n->end - n->begin;
  if (index == 0) {
    return n;
  } else if (0 < index && index < size) {
    Node *new_node = new Node{n->begin + index, n->end, n, n->next};
    n->end = new_node->begin;
    n->next = new_node;
    if (new_node->next != nullptr) {
      new_node->next->prev = new_node;
    }
    return new_node;
  }
  return update(n->next, index - size);
}

Node *tail(Node *n) {
  if (n->next == nullptr) {
    return n;
  }
  return tail(n->next);
}

void test(Node *n) {
  while (n != nullptr) {
    printf("[%d, %d)\\n", n->begin, n->end);
    n = n->next;
  }
  puts("---------------------------");
}

P intersect(int al, int ar, int bl, int br) {
  if (al <= bl && br <= ar) {
    return mp(bl, br);
  }
  if (bl <= al && ar <= br) {
    return mp(al, ar);
  }
  if (al <= bl && bl < ar) {
    return mp(bl, ar);
  }
  if (bl <= al && al < br) {
    return mp(al, br);
  }
  return mp(-1, -1);
}

int count(Node *root, int begin, int end, int v) {
  int pos = 0, res = 0;
  while (root != nullptr) {
    int size = root->end - root->begin;

    if (v - root->begin >= 0) {
      P is =
          intersect(begin, end, pos, pos + std::min(v - root->begin + 1, size));
      if (is.first != -1) {
        res += is.second - is.first;
      }
    }

    pos += size;
    root = root->next;
  }

  return res;
}

int main() {
  while (std::cin >> N >> M, N) {
    int p, q, r;
    std::cin >> p >> q >> r;

    Node *root = new Node{1, N + 1, nullptr, nullptr};
    REP(i, M) {
      int a, b;
      std::cin >> a >> b;

      // シャッフル前 [a1, ..., a2], [b1, ..., b2], [c1, ..., c2]
      // シャッフル後 [c1, ..., c2], [b1, ..., b2], [a1, ..., a2]
      // (a2後ろの接続を断つ)
      Node *a1 = root, *b1 = update(root, a), *c1 = update(root, b),
           *a2 = b1->prev, *b2 = c1->prev, *c2 = tail(root);

      // printf("a1: [%d, %d), a2: [%d, %d)\\n", a1->begin, a1->end, a2->begin,
      // a2->end); printf("b1: [%d, %d), b2: [%d, %d)\\n", b1->begin, b1->end,
      // b2->begin, b2->end); printf("c1: [%d, %d), c2: [%d, %d)\\n", c1->begin,
      // c1->end, c2->begin, c2->end);

      c2->next = b1;
      b1->prev = c2;
      b2->next = a1;
      a1->prev = b2;
      a2->next = nullptr;

      root = c1;
    }
    printf("%d\\n", count(root, p - 1, q, r));
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int, int> P;
typedef std::pair<int, P> State;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1},
          dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

int N, M;

struct Node {
  int begin, end;
  Node *prev, *next;
};

// 0, 1, 2, 3, 4, 5, 6, 7, 8
// 1, 2, 3, 4, 5, 6, 7, 8, 9
// [6, 7, 8, 9], [4, 5], [1, 2, 3]
Node *update(Node *n, int index) {
  int size = n->end - n->begin;
  if (index == 0) {
    return n;
  } else if (0 < index && index < size) {
    Node *new_node = new Node{n->begin + index, n->end, n, n->next};
    n->end = new_node->begin;
    n->next = new_node;
    return new_node;
  }
  return update(n->next, index - size);
}

Node *tail(Node *n) {
  if (n->next == nullptr) {
    return n;
  }
  return tail(n->next);
}

void test(Node *n) {
  while (n != nullptr) {
    printf("[%d, %d)\\n", n->begin, n->end);
    n = n->next;
  }
  puts("---------------------------");
}

P intersect(int al, int ar, int bl, int br) {
  if (al <= bl && br <= ar) {
    return mp(bl, br);
  }
  if (bl <= al && ar <= br) {
    return mp(al, ar);
  }
  if (al <= bl && bl < ar) {
    return mp(bl, ar);
  }
  if (bl <= al && al < br) {
    return mp(al, br);
  }
  return mp(-1, -1);
}

int count(Node *root, int begin, int end, int v) {
  int pos = 0, res = 0;
  while (root != nullptr) {
    int size = root->end - root->begin;

    if (v - root->begin >= 0) {
      P is =
          intersect(begin, end, pos, pos + std::min(v - root->begin + 1, size));
      if (is.first != -1) {
        res += is.second - is.first;
      }
    }

    pos += size;
    root = root->next;
  }

  return res;
}

int main() {
  while (std::cin >> N >> M, N) {
    int p, q, r;
    std::cin >> p >> q >> r;

    Node *root = new Node{1, N + 1, nullptr, nullptr};
    REP(i, M) {
      int a, b;
      std::cin >> a >> b;

      // シャッフル前 [a1, ..., a2], [b1, ..., b2], [c1, ..., c2]
      // シャッフル後 [c1, ..., c2], [b1, ..., b2], [a1, ..., a2]
      // (a2後ろの接続を断つ)
      Node *a1 = root, *b1 = update(root, a), *c1 = update(root, b),
           *a2 = b1->prev, *b2 = c1->prev, *c2 = tail(root);

      c2->next = b1;
      b1->prev = c2;
      b2->next = a1;
      a1->prev = b2;
      a2->next = nullptr;

      root = c1;
    }

    printf("%d\\n", count(root, p - 1, q, r));
  }
}