結果

問題 No.808 Kaiten Sushi?
ユーザー niuezniuez
提出日時 2019-03-22 22:45:24
言語 C++11
(gcc 11.4.0)
結果
WA  
実行時間 -
コード長 5,723 bytes
コンパイル時間 1,519 ms
コンパイル使用メモリ 169,276 KB
実行使用メモリ 17,204 KB
最終ジャッジ日時 2023-10-19 09:56:37
合計ジャッジ時間 6,966 ms
ジャッジサーバーID
(参考情報)
judge12 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 AC 3 ms
4,348 KB
testcase_08 AC 3 ms
4,348 KB
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 AC 47 ms
8,756 KB
testcase_24 AC 38 ms
7,536 KB
testcase_25 AC 42 ms
8,228 KB
testcase_26 AC 40 ms
7,964 KB
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 WA -
testcase_33 WA -
testcase_34 WA -
testcase_35 WA -
testcase_36 WA -
testcase_37 AC 2 ms
4,348 KB
testcase_38 AC 1 ms
4,348 KB
testcase_39 WA -
testcase_40 WA -
testcase_41 WA -
testcase_42 WA -
testcase_43 WA -
testcase_44 WA -
testcase_45 WA -
testcase_46 WA -
testcase_47 WA -
testcase_48 WA -
testcase_49 WA -
testcase_50 WA -
testcase_51 WA -
testcase_52 WA -
testcase_53 WA -
testcase_54 AC 1 ms
4,348 KB
testcase_55 AC 2 ms
4,348 KB
testcase_56 WA -
testcase_57 WA -
testcase_58 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

#include <utility>
using namespace std;

template<class Key, class T>
struct splay_map {
  struct node {
    node* left;
    node* right;
    node* parent; Key key;
    T val;
    size_t size;
    node(Key k, T v) : val(v), key(k), left(nullptr), right(nullptr), parent(nullptr){}
    ~node() {
      delete left , left = nullptr;
      delete right , right = nullptr;
    }
  };
  node* root;

  size_t subtree_size(node* x) {
    if(x) return x->size;
    return 0;
  }
  node* fix(node* n) {
    if(!n) return nullptr;
    n->size = subtree_size(n->left) + subtree_size(n->right) + 1;
    return n;
  }
  void setl(node* par, node* x) {
    if(par) par->left = x;
    if(x) x->parent = par;
    fix(par);
  }
  void setr(node* par, node* x) {
    if(par) par->right = x;
    if(x) x->parent = par;
    fix(par);
  }
  void zig(node* x) {
    node* p = x->parent;
    setl(p, x->right);
    if(p->parent) {
      if(p->parent->left == p) setl(p->parent, x);
      else setr(p->parent, x);
    }
    else x->parent = nullptr;
    setr(x, p);
  }
  void zag(node* x) {
    node* p = x->parent;
    setr(p, x->left);
    if(p->parent) {
      if(p->parent->left == p) setl(p->parent, x);
      else setr(p->parent, x);
    }
    else x->parent = nullptr;
    setl(x, p);
  }
  void splay(node* x) {
    if(!x) return;
    while(x->parent) {
      if(!x->parent->parent){
        if(x->parent->left == x) zig(x);
        else zag(x);
      }
      else if(x->parent->parent->left == x->parent && x->parent->left == x){
        zig(x->parent);
        zig(x);
      }
      else if(x->parent->parent->left == x->parent && x->parent->right == x){
        zag(x);
        zig(x);
      }
      else if(x->parent->parent->right == x->parent && x->parent->right == x){
        zag(x->parent);
        zag(x);
      }
      else{
        zig(x);
        zag(x);
      }
    }
    root = x;
  }

  bool find(Key key) {
    node* z = root;
    node* p = nullptr;
    while(z) {
      p = z;
      if(z->key == key) {
        splay(z);
        return true;
      }
      else if(z->key < key) {
        z = z->right;
      }
      else {
        z = z->left;
      }
    }
    splay(p);
    return false;
  }
  void insert(Key key, T val) {
    if(find(key)) return;
    node* z = new node(key, val);
    if(root == nullptr)
      root = z;
    else if(root->key < key) {
      setr(z, root->right);
      setr(root,z);
    }
    else {
      setl(z, root->left);
      setl(root, z);
    }
    splay(z);
  }
  void erase(Key key) {
    if(!find(key)) return;
    node* z = root;
    if(!z->left && !z->right)
      root = nullptr;
    else if(!z->left) {
      root = z->right;
      root->parent = nullptr;
    }
    else if(!z->right) {
      root = z->left;
      root->parent = nullptr;
    }
    else {
      node* lm = z->left;
      while(lm->right) {
        lm = lm->right;
      }
      z->left->parent = nullptr;
      splay(lm);
      root = lm;
      setr(root, z->right);
    }
  }
  T& value(const Key& key) {
    if(find(key)) {
      return root->value;
    }
  }
  size_t size() {
    return subtree_size(root);
  }
  Key nth_node(size_t n) {
    node* z = root;
    while(z) {
      if(subtree_size(z->left) == n) {
        return z->key;
      }
      if(subtree_size(z->left) < n) {
        n -= subtree_size(z->left) + 1;
        z = z->right;
      }
      else {
        z = z->left;
      }
    }
  }
  node* lower_bound(Key key) {
    node* z = root;
    node* x = nullptr;
    while(z) {
      if(key > z->key) {
        z = z->right;
      }
      else {
        x = z;
        z = z->left;
      }
    }
    return x;
  }

  node* search(Key key) {
    node* z = root;
    node* x = nullptr;
    while(z) {
      if(z->key <= key) {
        x = z;
        z = z->right;
      }
      else {
        z = z->left;
      }
    }
    return x;
  }

  splay_map() : root(nullptr) {}
  ~splay_map() { delete root; }
};

int main() {
  i64 N;
  i64 L;
  cin >> N >> L;

  vector<i64> x(N),y(N);
  for(int i = 0;i < N;i++) cin >> x[i];
  for(int i = 0;i < N;i++) cin >> y[i];

  splay_map<i64,i64> su, te;

  for(int i = 0;i < N;i++) su.insert(x[i] , 0);
  for(int i = 0;i < N;i++) te.insert(y[i] , 0);
  i64 now = 0;

  i64 ans = 0;

  auto func = [&](i64 sushi, i64 next) {
    if(sushi < next) {
      auto mm = te.search(next);
      if(mm == nullptr || mm->key < sushi) mm = nullptr;
      return mm;
    }
    else {
      auto mm = te.search(next);
      if(mm != nullptr) return mm;
      mm = te.search(1e18);
      return mm;
    }
  } ;

  for(int i = 0;i < N;i++) {
    auto n = su.lower_bound(now);
    if(n == nullptr || n->key < now) {
      n = su.lower_bound(0);
      ans = ((ans / L) + 1) * L;
    }
    i64 sushi = n->key;
    ans = (ans / L) * L + sushi;

    auto nn = su.lower_bound(sushi + 1);
    i64 NG = false;
    if(i == N - 1) { 
      NG = true;
    }
    else if(nn == nullptr) {
      nn = su.lower_bound(0);
    }
    if(!NG) {
      i64 next = nn->key;
      auto mm = func(sushi, next);
      if(mm == nullptr) NG = true;
      else {
        i64 tea = mm->key;
        if(sushi < tea) {
          ans = (ans / L) * L + tea;
        }
        else {
          ans = ((ans / L) + 1) * L + tea;
        }
        su.erase(sushi);
        te.erase(tea);
        now = tea;
      }
    }
    if(NG) {
      auto m = te.lower_bound(sushi);
      if(m == nullptr || n->key < sushi) {
        m = te.lower_bound(0);
        ans = ((ans / L) + 1) * L;
      }
      i64 tea = m->key;
      ans = (ans / L) * L + tea;
      su.erase(sushi);
      te.erase(tea);
      now = tea;
    }
  }

  cout << ans << endl;
}
0