結果
| 問題 |
No.808 Kaiten Sushi?
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-03-22 22:45:24 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 5,723 bytes |
| コンパイル時間 | 1,516 ms |
| コンパイル使用メモリ | 167,580 KB |
| 実行使用メモリ | 17,408 KB |
| 最終ジャッジ日時 | 2024-09-19 06:08:41 |
| 合計ジャッジ時間 | 6,262 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 WA * 1 |
| other | AC * 8 WA * 48 |
ソースコード
#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;
}