Problem:
Problem G: The Humans Braving the Invaders
Problem
現在、地球は宇宙からの侵略者であるインベーダーの攻撃を受け、人類で生き残った者は基地にいる我々だけとなった。
奴らに対抗できる戦力もほとんど残されていない。
だが、ここで我々は諦めるということはしない。
インベーダを全滅させることが、我々人類が生き残る最後の手段である。
今から最後になるであろう作戦の内容を説明する。
まず、インベーダーの戦力に比べ我々の戦力はあまりにも少ないので、この基地に立てこもり、籠城戦を行う。
この基地は高い山に囲まれていて、インベーダーが侵攻するには基地正面にある真っ直ぐな道を通る他無い。
この道をフィールドと呼ぶことにする。この特徴により、前方に集中してインベーダーを攻撃することが可能である。
基地にいる我々はインベーダーに対し2種類の武器で攻撃を行う。
1つはインベーダー1体を狙撃するスナイパーライフルである。もう1つは広範囲に攻撃ができるグレネードランチャーである。
人類でたった1人のプログラマーである君の仕事は、インベーダーと我々の行動記録を元に戦闘をシミュレーションすることだ。
行動記録はクエリー形式で与えられる。各クエリーは1つまたは複数の整数からなり、次のように与えられる。
0
インベーダーがフィールド上の、基地からの距離
L
の位置に出現する。
1
d
現在フィールド上にいるすべてのインベーダーが
d
だけ基地に近づく。
この動作の後、基地に到達したインベーダーからダメージを受け、また、それらの敵はフィールド上から消滅する。
ダメージを受けた場合は"damage (この時基地に到達したインベーダーの数)"を1行に出力する。
2
k
現在フィールド上にいるインベーダーの数が
k
体以上の場合、基地に近い方から
k
番目のインベーダーをスナイパーライフルで攻撃する。
そのインベーダーはフィールド上から消滅する。そして"hit"を1行に出力する。
フィールド上のインベーダーの数が
k
体未満の場合、"miss"を1行に出力する。
3
x
r
基地からの距離が
x
の位置に範囲
r
のグレネードランチャーで攻撃する。基地からの距離が
x
の位置に着弾し、そこからの距離が
r
以下の位置にいるすべてのインベーダーはフィールド上から消滅する。
そして"bomb (倒したインベーダーの数)"を1行に出力する。補足として、基地はグレネードランチャーのダメージを受けることはない。
4
k
フィールド上のインベーダーの数が
k
体以上の場合、"distance (基地に近い方からk番目のインベーダーと基地との距離)"を1行に出力する。
フィールド上のインベーダーの数が
k
体未満の場合、"distance -1"を1行に出力する。
作戦の説明は以上だ。総員、作戦開始！・・・幸運を祈る。
Input
入力は複数のデータセットからなる。
各データセットは以下で表される。
1行目は2つの整数
Q
,
L
がスペース区切りで与えられる。
続く
Q
行には、上記で説明したクエリーが
Q
個与えられる。
入力の終わりは2つのゼロからなる。
Constraints
入力は以下の条件を満たす。
入力に含まれる値はすべて整数
1 ≤
Q
≤ 100000
1 ≤
L
≤ 10
9
1 ≤
d
,
k
≤ 10
9
0 ≤
x
≤
L
0 ≤
r
≤ 10
9
同じ位置にインベーダーが2体以上存在することはない
データセットの数は3個以下
Output
各データセットにつき、出力の指示があるクエリーに対して出力せよ。各データセットの最後には"end"を出力せよ。
Sample Input
18 10
0
4 1
1 1
4 1
0
1 1
0
2 2
1 10
0
1 1
0
1 1
0
1 5
3 4 0
3 4 1
0
9 10
4 1
2 2
3 5 5
0
4 1
2 2
3 5 5
0
2 1
0 0
Sample Output
distance 10
distance 9
hit
damage 2
bomb 1
bomb 2
end
distance -1
miss
bomb 0
distance 10
miss
bomb 1
hit
end

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

class BIT {
public:
	int size_ = 1;
	vector<int> dat;

	void init(int sz) {
		size_ = sz + 2;
		dat.resize(size_ + 2, 0);
	}

	void add(int pos, int x) {
		pos += 1;
		while (pos <= size_) {
			dat[pos] += x;
			pos += (pos & -pos);
		}
	}

	int sum(int pos) {
		int s = 0; pos += 1;
		while (pos >= 1) {
			s += dat[pos];
			pos -= (pos & -pos);
		}
		return s;
	}
};

long long Q, T[100009], A[100009], B[100009];
long long L;
vector<long long> Zahyou;
set<pair<long long, long long>> Set;
BIT Z;

void Initialize() {
	Zahyou.clear();
	Set.clear();
	Z.size_ = 1;
	Z.dat = vector<int>{};
}

int Binary_Search(int num) {
	int cl = 0, cr = Zahyou.size() + 1, cm, minx = (1 << 30);
	for (int i = 0; i < 25; i++) {
		cm = (cl + cr) / 2;
		int r = Z.sum(cm);
		if (r >= num) { cr = cm; minx = min(minx, cm); }
		else { cl = cm; }
	}
	return minx;
}

// 範囲 [cl, cr]
vector<long long> SetRange(long long cl, long long cr) {
	vector<long long> ret;
	while (true) {
		auto itr = Set.lower_bound(make_pair(cl, -1));
		if (itr == Set.end()) break;
		if ((*itr).first > cr) break;
		ret.push_back((*itr).second);
		Set.erase(itr);
	}
	return ret;
}

int main() {
	while (true) {
		Initialize();

		// Step 1. Input
		cin >> Q >> L; if (Q + L == 0) break;
		for (int i = 1; i <= Q; i++) {
			cin >> T[i];
			if (T[i] == 1) cin >> A[i];
			if (T[i] == 2) cin >> A[i];
			if (T[i] == 3) cin >> A[i] >> B[i];
			if (T[i] == 4) cin >> A[i];
		}

		// Step 2. Compression
		long long Cursor = L;
		for (int i = 1; i <= Q; i++) {
			if (T[i] == 0) Zahyou.push_back(Cursor);
			if (T[i] == 1) Cursor += A[i];
		}
		sort(Zahyou.begin(), Zahyou.end());
		Zahyou.erase(unique(Zahyou.begin(), Zahyou.end()), Zahyou.end());
		Z.init(Zahyou.size() + 2);

		// Step 3. Query
		Cursor = 0;
		for (int i = 1; i <= Q; i++) {
			if (T[i] == 0) {
				int pos1 = lower_bound(Zahyou.begin(), Zahyou.end(), Cursor + L) - Zahyou.begin();
				Set.insert(make_pair(Cursor + L, pos1));
				Z.add(pos1, 1);
			}

			// 進撃
			if (T[i] == 1) {
				Cursor += A[i];
				vector<long long> vec = SetRange(0, Cursor);
				for (long long place : vec) { Z.add(place, -1); }
				if (vec.size() != 0) cout << "damage " << vec.size() << endl;
			}

			// 単体攻撃
			if (T[i] == 2) {
				int ret = Binary_Search(A[i]);
				if (ret == (1 << 30)) cout << "miss" << endl;
				else {
					Z.add(ret, -1);
					Set.erase(make_pair(Zahyou[ret], ret));
					cout << "hit" << endl;
				}
			}

			// 範囲攻撃
			if (T[i] == 3) {
				vector<long long> vec = SetRange(Cursor + A[i] - B[i], Cursor + A[i] + B[i]);
				for (long long place : vec) { Z.add(place, -1); }
				cout << "bomb " << vec.size() << endl;
			}

			// 距離の確認
			if (T[i] == 4) {
				int ret = Binary_Search(A[i]);
				if (ret == (1 << 30)) cout << "distance " << -1 << endl;
				else cout << "distance " << Zahyou[ret] - Cursor << endl;
			}
		}

		// 最後
		cout << "end" << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 8308
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

class BIT {
public:
	int size_ = 1;
	vector<int> dat;

	void init(int sz) {
		size_ = sz + 2;
		dat.resize(size_ + 2, 0);
	}

	void add(int pos, int x) {
		pos += 1;
		while (pos <= size_) {
			dat[pos] += x;
			pos += (pos & -pos);
		}
	}

	int sum(int pos) {
		int s = 0; pos += 1;
		while (pos >= 1) {
			s += dat[pos];
			pos -= (pos & -pos);
		}
		return s;
	}
};

int Q, T[100009], A[100009], B[100009];
int L;
vector<int> Zahyou;
set<pair<int, int>> Set;
BIT Z;

void Initialize() {
	Zahyou.clear();
	Set.clear();
	Z.size_ = 1;
	Z.dat = vector<int>{};
}

int Binary_Search(int num) {
	int cl = 0, cr = Zahyou.size() + 1, cm, minx = (1 << 30);
	for (int i = 0; i < 25; i++) {
		cm = (cl + cr) / 2;
		int r = Z.sum(cm);
		if (r >= num) { cr = cm; minx = min(minx, cm); }
		else { cl = cm; }
	}
	return minx;
}

// 範囲 [cl, cr]
vector<int> SetRange(int cl, int cr) {
	vector<int> ret;
	while (true) {
		auto itr = Set.lower_bound(make_pair(cl, -1));
		if (itr == Set.end()) break;
		if ((*itr).first > cr) break;
		ret.push_back((*itr).second);
		Set.erase(itr);
	}
	return ret;
}

int main() {
	while (true) {
		Initialize();

		// Step 1. Input
		cin >> Q >> L; if (Q + L == 0) break;
		for (int i = 1; i <= Q; i++) {
			cin >> T[i];
			if (T[i] == 1) cin >> A[i];
			if (T[i] == 2) cin >> A[i];
			if (T[i] == 3) cin >> A[i] >> B[i];
			if (T[i] == 4) cin >> A[i];
		}

		// Step 2. Compression
		int Cursor = L;
		for (int i = 1; i <= Q; i++) {
			if (T[i] == 0) Zahyou.push_back(Cursor);
			if (T[i] == 1) Cursor += A[i];
		}
		sort(Zahyou.begin(), Zahyou.end());
		Zahyou.erase(unique(Zahyou.begin(), Zahyou.end()), Zahyou.end());
		Z.init(Zahyou.size() + 2);

		// Step 3. Query
		Cursor = 0;
		for (int i = 1; i <= Q; i++) {
			if (T[i] == 0) {
				int pos1 = lower_bound(Zahyou.begin(), Zahyou.end(), Cursor + L) - Zahyou.begin();
				Set.insert(make_pair(Cursor + L, pos1));
				Z.add(pos1, 1);
			}

			// 進撃
			if (T[i] == 1) {
				Cursor += A[i];
				vector<int> vec = SetRange(0, Cursor);
				for (int place : vec) { Z.add(place, -1); }
				if (vec.size() != 0) cout << "damage " << vec.size() << endl;
			}

			// 単体攻撃
			if (T[i] == 2) {
				int ret = Binary_Search(A[i]);
				if (ret == (1 << 30)) cout << "miss" << endl;
				else {
					Z.add(ret, -1);
					Set.erase(make_pair(Zahyou[ret], ret));
					cout << "hit" << endl;
				}
			}

			// 範囲攻撃
			if (T[i] == 3) {
				vector<int> vec = SetRange(Cursor + A[i] - B[i], Cursor + A[i] + B[i]);
				for (int place : vec) { Z.add(place, -1); }
				cout << "bomb " << vec.size() << endl;
			}

			// 距離の確認
			if (T[i] == 4) {
				int ret = Binary_Search(A[i]);
				if (ret == (1 << 30)) cout << "distance " << -1 << endl;
				else cout << "distance " << Zahyou[ret] - Cursor << endl;
			}
		}

		// 最後
		cout << "end" << endl;
	}
	return 0;
}
accuracy: 0.15384615384615385
time_ms: 60
memory_kb: 6372
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 100005

int num_Q;
ll L,bit_N;
ll A[SIZE],table[SIZE];
ll BIT[SIZE];
bool is_del[SIZE];


ll min_data[6*SIZE],add_data[6*SIZE];
int N = 1;

void bit_add(ll loc,ll value){

	BIT[loc] += value;

	loc += loc & -loc;

	while(loc <= bit_N){
		BIT[loc] += value;
		loc += loc & -loc;
	}
}

ll getSum(ll loc){

	if(loc == 0)return 0;

	ll sum = BIT[loc];

	loc -= loc & -loc;

	while(loc > 0){
		sum += BIT[loc];
		loc -= loc & -loc;
	}
	return sum;
}

void init(ll first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,ll value,int node_id,int node_left,int node_right){

	if(right < node_left || left > node_right){
		//範囲外ならreturn
		return;
	}
	else if(left <= node_left && right >= node_right){ //このノードのカバーしている区間が、更新区間の部分区間である場合

		add_data[node_id] += value; //一様に加える値を加算

		while(node_id != 0){

			node_id = (node_id-1)/2; //下から上に向かって、最小値および最大値更新
			min_data[node_id] = min(min_data[2*node_id+1]+add_data[2*node_id+1],min_data[2*node_id+2]+add_data[2*node_id+2]);
		}
	}else{

		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right);
	}
}

ll getMin(int left,int right,int node_id,int node_left,int node_right){
	if(right < node_left || left > node_right)return HUGE_NUM;
	else if(left <= node_left && right >= node_right){
		return min_data[node_id]+add_data[node_id];

	}else{

		ll  left_min  = getMin(left,right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll  right_min = getMin(left,right,2*node_id+2,(node_left+node_right)/2+1,node_right);
		return min(left_min,right_min)+add_data[node_id];
	}
}

int getPos(int num){

	int left = 1,right = bit_N,mid = (left+right)/2;
	int ret = -1;

	while(left <= right){

		if(getSum(mid) >= num){

			ret = mid;
			right = mid-1;
		}else{

			left = mid+1;
		}
		mid = (left+right)/2;
	}
	return ret;
}


void func(){

	int first_N = 0;

	bit_N = num_Q;

	N = 1;
	init(num_Q);

	for(int i = 0; i <= bit_N; i++){

		BIT[i] = 0;
		is_del[i] = false;
	}


	for(ll i = 0; i <= 2*N-2; i++){
		min_data[i] = 0;
		add_data[i] = 0;
	}


	int command;
	ll dist;
	ll k;
	ll x,r;

	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);

		if(command == 0){ //敵出現

			add(first_N,first_N,L,0,0,N-1);
			bit_add(first_N+1,1);
			first_N++;

		}else if(command == 1){

			scanf("%lld",&dist);

			add(0,first_N-1,-dist,0,0,N-1);

			//二分探索で、0以下となる最大のindexを求める
			int left = 0,right = first_N-1,mid = (left+right)/2;
			int loc = -1;

			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= 0){

					loc = mid;
					left = mid+1;

				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			if(loc == -1){

				continue;
			}

			//0～locまでで生きてるデータの数
			int tmp_sum = getSum(loc+1);
			if(tmp_sum == 0){

				continue;
			}

			printf("damage %d\n",tmp_sum);
			for(int i = 1; i <= loc+1; i++){ //論理削除
				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}

		}else if(command == 2){

			scanf("%lld",&k);

			if(getSum(bit_N) < k){

				printf("miss\n");
			}else{

				int pos = getPos(k);
				printf("hit\n");

				bit_add(pos,-1);
				is_del[pos] = true;
			}

		}else if(command == 3){

			scanf("%lld %lld",&x,&r);

			int L = -1,R = -1;

			int left = 0,right = first_N-1,mid = (left+right)/2;
			//二分探索で、x-r以上となる最も左の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp >= x-r){

					L = mid;
					right = mid-1;
				}else{

					left = mid+1;
				}
				mid = (left+right)/2;
			}

			if(L == -1){

				printf("bomb 0\n");
				continue;
			}

			left = 0,right = first_N-1,mid = (left+right)/2;

			//二分探索で、x+r以下となる最も右の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= x+r){

					R = mid;
					left = mid+1;
				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			ll tmp = getSum(R+1)-getSum(L);
			printf("bomb %lld\n",tmp);

			for(int i = L+1; i <= R+1; i++){

				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}


		}else{ //command == 4

			scanf("%lld",&k);
			if(getSum(bit_N) < k){

				printf("distance -1\n");
			}else{

				int pos = getPos(k);
				printf("distance %lld\n",getMin(pos-1,pos-1,0,0,N-1));
			}
		}
	}
	printf("end\n");
}

int main(){

	while(true){

		scanf("%d %lld",&num_Q,&L);
		if(num_Q == 0 && L == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 8220
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 100005

int num_Q;
ll L,bit_N;
ll A[SIZE],table[SIZE];
ll BIT[SIZE];
bool is_del[SIZE];


ll min_data[6*SIZE],add_data[6*SIZE];
int N = 1;

void bit_add(ll loc,ll value){

	BIT[loc] += value;

	loc += loc & -loc;

	while(loc <= bit_N){
		BIT[loc] += value;
		loc += loc & -loc;
	}
}

ll getSum(ll loc){

	if(loc == 0)return 0;

	ll sum = BIT[loc];

	loc -= loc & -loc;

	while(loc > 0){
		sum += BIT[loc];
		loc -= loc & -loc;
	}
	return sum;
}

void init(ll first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,ll value,int node_id,int node_left,int node_right){

	if(right < node_left || left > node_right){
		//範囲外ならreturn
		return;
	}
	else if(left <= node_left && right >= node_right){ //このノードのカバーしている区間が、更新区間の部分区間である場合

		add_data[node_id] += value; //一様に加える値を加算

		while(node_id != 0){

			node_id = (node_id-1)/2; //下から上に向かって、最小値および最大値更新
			min_data[node_id] = min(min_data[2*node_id+1]+add_data[2*node_id+1],min_data[2*node_id+2]+add_data[2*node_id+2]);
		}
	}else{

		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right);
	}
}

ll getMin(int left,int right,int node_id,int node_left,int node_right){
	if(right < node_left || left > node_right)return HUGE_NUM;
	else if(left <= node_left && right >= node_right){
		return min_data[node_id]+add_data[node_id];

	}else{

		ll  left_min  = getMin(left,right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll  right_min = getMin(left,right,2*node_id+2,(node_left+node_right)/2+1,node_right);
		return min(left_min,right_min)+add_data[node_id];
	}
}

int getPos(int num){

	int left = 1,right = bit_N,mid = (left+right)/2;
	int ret = -1;

	while(left <= right){

		if(getSum(mid) >= num){

			ret = mid;
			right = mid-1;
		}else{

			left = mid+1;
		}
		mid = (left+right)/2;
	}
	return ret;
}


void func(){

	int first_N = 0;

	bit_N = num_Q;

	N = 1;
	init(num_Q);

	for(int i = 0; i <= bit_N; i++){

		BIT[i] = 0;
		is_del[i] = false;
	}


	for(ll i = 0; i <= 2*N-2; i++){
		min_data[i] = 0;
		add_data[i] = 0;
	}


	int command;
	ll dist;
	ll k;
	ll x,r;

	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);

		//printf("\nloop:%d\n",loop);

		if(command == 0){ //敵出現

			add(first_N,first_N,L,0,0,N-1);
			bit_add(first_N+1,1);
			first_N++;

		}else if(command == 1){

			scanf("%lld",&dist);

			add(0,first_N-1,-dist,0,0,N-1);

			//二分探索で、0以下となる最大のindexを求める
			int left = 0,right = first_N-1,mid = (left+right)/2;
			int loc = -1;

			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= 0){

					loc = mid;
					left = mid+1;

				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			if(loc == -1){

				continue;
			}

			//0～locまでで生きてるデータの数
			int tmp_sum = getSum(loc+1);
			if(tmp_sum == 0){

				continue;
			}

			//printf("loc:%d\n",loc);
			printf("damage %d\n",tmp_sum);
			for(int i = 1; i <= loc+1; i++){ //論理削除
				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}

		}else if(command == 2){

			scanf("%lld",&k);

			if(getSum(bit_N) < k){

				printf("miss\n");
			}else{

				int pos = getPos(k);
				printf("hit\n");

				bit_add(pos,-1);
				is_del[pos] = true;
			}

		}else if(command == 3){

			scanf("%lld %lld",&x,&r);

			int L = -1,R = -1;

			int left = 0,right = first_N-1,mid = (left+right)/2;
			//二分探索で、x-r以上となる最も左の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp >= x-r){

					L = mid;
					right = mid-1;
				}else{

					left = mid+1;
				}
				mid = (left+right)/2;
			}

			if(L == -1){

				printf("bomb 0\n");
				continue;
			}

			left = 0,right = first_N-1,mid = (left+right)/2;

			//二分探索で、x+r以下となる最も右の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= x+r){

					R = mid;
					left = mid+1;
				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			ll tmp = getSum(R+1)-getSum(L);
			printf("bomb %lld\n",tmp);

			for(int i = L+1; i <= R+1; i++){

				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}


		}else{ //command == 4

			scanf("%lld",&k);
			if(getSum(bit_N) < k){

				printf("distance -1\n");
			}else{

				int pos = getPos(k);
				printf("distance %lld\n",getMin(pos-1,pos-1,0,0,N-1));
			}
		}
	}
	printf("end\n");
}

int main(){

	while(true){

		scanf("%d %lld",&num_Q,&L);
		if(num_Q == 0 && L == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 8216
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 100005

int num_Q;
ll L,bit_N;
ll A[SIZE],table[SIZE];
ll BIT[SIZE];
bool is_del[SIZE];


ll min_data[6*SIZE],add_data[6*SIZE];
int N = 1;

void bit_add(ll loc,ll value){

	BIT[loc] += value;

	loc += loc & -loc;

	while(loc <= bit_N){
		BIT[loc] += value;
		loc += loc & -loc;
	}
}

ll getSum(ll loc){

	if(loc == 0)return 0;

	ll sum = BIT[loc];

	loc -= loc & -loc;

	while(loc > 0){
		sum += BIT[loc];
		loc -= loc & -loc;
	}
	return sum;
}

void init(ll first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,ll value,int node_id,int node_left,int node_right){

	if(right < node_left || left > node_right){
		//範囲外ならreturn
		return;
	}
	else if(left <= node_left && right >= node_right){ //このノードのカバーしている区間が、更新区間の部分区間である場合

		add_data[node_id] += value; //一様に加える値を加算

		while(node_id != 0){

			node_id = (node_id-1)/2; //下から上に向かって、最小値および最大値更新
			min_data[node_id] = min(min_data[2*node_id+1]+add_data[2*node_id+1],min_data[2*node_id+2]+add_data[2*node_id+2]);
		}
	}else{

		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right);
	}
}

ll getMin(int left,int right,int node_id,int node_left,int node_right){
	if(right < node_left || left > node_right)return HUGE_NUM;
	else if(left <= node_left && right >= node_right){
		return min_data[node_id]+add_data[node_id];

	}else{

		ll  left_min  = getMin(left,right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll  right_min = getMin(left,right,2*node_id+2,(node_left+node_right)/2+1,node_right);
		return min(left_min,right_min)+add_data[node_id];
	}
}

int getPos(int num){

	int left = 1,right = bit_N,mid = (left+right)/2;
	int ret = -1;

	while(left <= right){

		if(getSum(mid) >= num){

			ret = mid;
			right = mid-1;
		}else{

			left = mid+1;
		}
		mid = (left+right)/2;
	}
	return ret;
}


void func(){

	int first_N = 0;

	bit_N = num_Q;

	N = 1;
	init(num_Q);

	for(int i = 0; i <= bit_N; i++){

		BIT[i] = 0;
		is_del[i] = false;
	}


	for(ll i = 0; i <= 2*N-2; i++){
		min_data[i] = 0;
		add_data[i] = 0;
	}


	int command;
	ll dist;
	ll k;
	ll x,r;

	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);

		//printf("\nloop:%d\n",loop);

		if(command == 0){ //敵出現

			add(first_N,first_N,L,0,0,N-1);
			bit_add(first_N+1,1);
			first_N++;

		}else if(command == 1){

			scanf("%lld",&dist);

			add(0,first_N-1,-dist,0,0,N-1);

			//二分探索で、0以下となる最大のindexを求める
			int left = 0,right = first_N-1,mid = (left+right)/2;
			int loc = -1;

			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= 0){

					loc = mid;
					left = mid+1;

				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			if(loc == -1){

				continue;
			}

			//0～locまでで生きてるデータの数
			int tmp_sum = getSum(loc+1);
			if(tmp_sum == 0){

				continue;
			}

			//printf("loc:%d\n",loc);
			printf("damage %d\n",tmp_sum);
			for(int i = 1; i <= tmp_sum; i++){ //論理削除
				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}

		}else if(command == 2){

			scanf("%lld",&k);

			if(getSum(bit_N) < k){

				printf("miss\n");
			}else{

				int pos = getPos(k);
				printf("hit\n");
				bit_add(pos,-1);
			}

		}else if(command == 3){

			scanf("%lld %lld",&x,&r);

			int L = -1,R = -1;

			int left = 0,right = first_N-1,mid = (left+right)/2;
			//二分探索で、x-r以上となる最も左の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp >= x-r){

					L = mid;
					right = mid-1;
				}else{

					left = mid+1;
				}
				mid = (left+right)/2;
			}

			if(L == -1){

				printf("bomb 0\n");
				continue;
			}

			left = 0,right = first_N-1,mid = (left+right)/2;

			//二分探索で、x+r以下となる最も右の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= x+r){

					R = mid;
					left = mid+1;
				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			ll tmp = getSum(R+1)-getSum(L);
			printf("bomb %lld\n",tmp);

			for(int i = L+1; i <= R+1; i++){

				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}


		}else{ //command == 4

			scanf("%lld",&k);
			if(getSum(bit_N) < k){

				printf("distance -1\n");
			}else{

				int pos = getPos(k);
				printf("distance %lld\n",getMin(pos-1,pos-1,0,0,N-1));
			}
		}
	}
	printf("end\n");
}

int main(){

	while(true){

		scanf("%d %lld",&num_Q,&L);
		if(num_Q == 0 && L == 0)break;

		func();
	}

	return 0;
}
accuracy: 0.15384615384615385
time_ms: 290
memory_kb: 8144
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001


#define SIZE 100005

int num_Q;
ll L,bit_N;
ll A[SIZE],table[SIZE];
ll BIT[SIZE];
bool is_del[SIZE];


ll min_data[6*SIZE],add_data[6*SIZE];
int N = 1;

void bit_add(ll loc,ll value){

	BIT[loc] += value;

	loc += loc & -loc;

	while(loc <= bit_N){
		BIT[loc] += value;
		loc += loc & -loc;
	}
}

ll getSum(ll loc){

	if(loc == 0)return 0;

	ll sum = BIT[loc];

	loc -= loc & -loc;

	while(loc > 0){
		sum += BIT[loc];
		loc -= loc & -loc;
	}
	return sum;
}

void init(ll first_N){
	while(N < first_N)N *= 2;
}

void add(int left,int right,ll value,int node_id,int node_left,int node_right){

	if(right < node_left || left > node_right){
		//範囲外ならreturn
		return;
	}
	else if(left <= node_left && right >= node_right){ //このノードのカバーしている区間が、更新区間の部分区間である場合

		add_data[node_id] += value; //一様に加える値を加算

		while(node_id != 0){

			node_id = (node_id-1)/2; //下から上に向かって、最小値および最大値更新
			min_data[node_id] = min(min_data[2*node_id+1]+add_data[2*node_id+1],min_data[2*node_id+2]+add_data[2*node_id+2]);
		}
	}else{

		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right);
	}
}

ll getMin(int left,int right,int node_id,int node_left,int node_right){
	if(right < node_left || left > node_right)return BIG_NUM;
	else if(left <= node_left && right >= node_right){
		return min_data[node_id]+add_data[node_id];

	}else{

		ll  left_min  = getMin(left,right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll  right_min = getMin(left,right,2*node_id+2,(node_left+node_right)/2+1,node_right);
		return min(left_min,right_min)+add_data[node_id];
	}
}

int getPos(int num){

	int left = 1,right = bit_N,mid = (left+right)/2;
	int ret = -1;

	while(left <= right){

		if(getSum(mid) >= num){

			ret = mid;
			right = mid-1;
		}else{

			left = mid+1;
		}
		mid = (left+right)/2;
	}
	return ret;
}


void func(){

	int first_N = 0;

	bit_N = num_Q;

	N = 1;
	init(num_Q);

	for(int i = 0; i <= bit_N; i++){

		BIT[i] = 0;
		is_del[i] = false;
	}


	for(ll i = 0; i <= 2*N-2; i++){
		min_data[i] = 0;
		add_data[i] = 0;
	}


	int command;
	ll dist;
	ll k;
	ll x,r;

	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);

		//printf("\nloop:%d\n",loop);

		if(command == 0){ //敵出現

			add(first_N,first_N,L,0,0,N-1);
			bit_add(first_N+1,1);
			first_N++;

		}else if(command == 1){

			scanf("%lld",&dist);

			add(0,first_N-1,-dist,0,0,N-1);

			//二分探索で、0以下となる最大のindexを求める
			int left = 0,right = first_N-1,mid = (left+right)/2;
			int loc = -1;

			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= 0){

					loc = mid;
					left = mid+1;

				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			if(loc == -1){

				continue;
			}

			//0～locまでで生きてるデータの数
			int tmp_sum = getSum(loc+1);
			if(tmp_sum == 0){

				continue;
			}

			//printf("loc:%d\n",loc);
			printf("damage %d\n",tmp_sum);
			for(int i = 1; i <= tmp_sum; i++){ //論理削除
				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}

		}else if(command == 2){

			scanf("%lld",&k);

			if(getSum(bit_N) < k){

				printf("miss\n");
			}else{

				int pos = getPos(k);
				printf("hit\n");
				bit_add(pos,-1);
			}

		}else if(command == 3){

			scanf("%lld %lld",&x,&r);

			int L = -1,R = -1;

			int left = 0,right = first_N-1,mid = (left+right)/2;
			//二分探索で、x-r以上となる最も左の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp >= x-r){

					L = mid;
					right = mid-1;
				}else{

					left = mid+1;
				}
				mid = (left+right)/2;
			}

			if(L == -1){

				printf("bomb 0\n");
				continue;
			}

			left = 0,right = first_N-1,mid = (left+right)/2;

			//二分探索で、x+r以下となる最も右の位置を求める
			while(left <= right){

				ll tmp = getMin(mid,mid,0,0,N-1);
				if(tmp <= x+r){

					R = mid;
					left = mid+1;
				}else{

					right = mid-1;
				}
				mid = (left+right)/2;
			}

			ll tmp = getSum(R+1)-getSum(L);
			printf("bomb %lld\n",tmp);

			for(int i = L+1; i <= R+1; i++){

				if(is_del[i])continue;
				bit_add(i,-1);
				is_del[i] = true;
			}


		}else{ //command == 4

			scanf("%lld",&k);
			if(getSum(bit_N) < k){

				printf("distance -1\n");
			}else{

				int pos = getPos(k);
				printf("distance %lld\n",getMin(pos-1,pos-1,0,0,N-1));
			}
		}
	}
	printf("end\n");
}

int main(){

	while(true){

		scanf("%d %lld",&num_Q,&L);
		if(num_Q == 0 && L == 0)break;

		func();
	}

	return 0;
}
accuracy: 0.15384615384615385
time_ms: 280
memory_kb: 8172
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const ll MOD = 1e9 + 7;
double EPS = 1e-8;


#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/tag_and_trait.hpp>
using namespace __gnu_pbds;

using Tree = tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int Q, L;
    while(cin >> Q >> L) {
        if(Q == 0 && L == 0) break;
        Tree st;

        ll cur = 0LL;

        rep(i, Q) {

            // cout << i << " cur " << cur << " st[";
            // for(auto&& j : st) cout << j << ", ";
            //     cout << "]" << endl;

            int query;
            cin >> query;
            if (query == 0) {
                st.insert(L + cur);
            } else if (query == 1) {
                ll d;
                cin >> d;
                cur += d;
                int cnt = 0;
                while (st.size() > 0 && *st.begin() <= cur) {
                    cnt++;
                    st.erase(st.begin());
                }
                if(cnt > 0 ) cout << "damage " << cnt << '\n';
            } else if (query == 2) {
                int k;
                cin >> k;
                auto it = st.find_by_order(k - 1);
                if (it == st.end()) cout << "miss" << '\n';
                else {
                    cout << "hit" << '\n';
                    st.erase(it);
                }
            } else if (query == 3) {
                ll x, r;
                cin >> x >> r;
                ll L = cur + x - r, R = cur + x + r;
                int cnt = 0;
                auto it = st.lower_bound(L);
                while (it != st.end() && *it <= R) {
                    ++cnt;
                    it = st.erase(it);
                }
                cout << "bomb " << cnt << endl;
            } else {
                int k;
                cin >> k;
                auto it = st.find_by_order(k - 1);
                if (it == st.end()) cout << "distance -1" << '\n';
                else {
                    cout << "distance " << (*it) - cur << '\n';
                }
            }
        }
        cout << "end" << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 6316
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

template< typename T >
class Treap {
private: // parts
	unsigned int rnd() {
		static unsigned int x = 123456789, y = 362436069, z = 521288629, w = 88675123;
		unsigned int t = (x ^ (x << 11));
		x = y; y = z; z = w;
		return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
	}
	
	struct Node {
		T val, data, add;
		Node *lch, *rch;
		int pri, cnt;
		bool rev;
		
		Node(T v, int p) : val(v), data(v), add(T(0)), pri(p), cnt(1), rev(false) { lch = rch = nullptr; }
	};
	
	Node *root;
	
private: // main function
	int count(Node* t) { return t ? t->cnt : 0; }
	T data(Node* t) { return t ? t->data : T(1e9); }	
	
	void push(Node* t) {
		if (t && t->rev) {
			swap(t->lch, t->rch);
			if (t->lch) t->lch->rev ^= true;
			if (t->rch) t->rch->rev ^= true;
			t->rev = false;
		}
		
		if (t && t->add != 0) {
			t->val += t->add;
			if (t->lch) t->lch->add += t->add;
			if (t->rch) t->rch->add += t->add;
			t->add = 0;
		}
	}
	
	Node* update(Node *t) {
		if (!t) return t;
		t->cnt = count(t->lch) + count(t->rch) + 1;
		//t->data = calc(calc(data(t->lch), data(t->rch)), t->val);
		return t;
	}
	
	Node* merge(Node* l, Node* r) {
		push(l); push(r);
		
		if (!l || !r) return l ? l : r;
	
		if (l->pri > r->pri) {
			l->rch = merge(l->rch, r);
			return update(l);
		} else {
			r->lch = merge(l, r->lch);
			return update(r);
		}
	}
	
	typedef pair< Node*, Node* > pnn;
	
	pnn split(Node* t, int k) {
		if (!t) return pnn(nullptr, nullptr);
		
		push(t);
		
		if (k <= count(t->lch)) {
			pnn s = split(t->lch, k);
			t->lch = s.second;
			return pnn(s.first, update(t));
		} else {
			pnn s = split(t->rch, k - count(t->lch) - 1);
			t->rch = s.first;
			return pnn(update(t), s.second);
		}
	}
	
	Node* insert(Node* t, int k, T val, int pri) {
		pnn s = split(t, k);
		t = merge(s.first, new Node(val, pri));
		t = merge(t, s.second);
		return update(t);
	}
	
	Node* erase(Node* t, int k) {
		pnn s1 = split(t, k + 1);
		pnn s2 = split(s1.first, k);
		t = merge(s2.first, s1.second);
		delete s2.second;
		return update(t);
	}
	
	Node* find(Node* t, int k) {
		push(t);
		int c = count(t->lch);
		if (k < c) return find(t->lch, k);
		if (k > c) return find(t->rch, k - c - 1);
		return t;
	}
	
	void dump(Node* t, ostream& os) {
		if (!t) return;
		os << "(";
		dump(t->lch, os);
		os << t->val;
		dump(t->rch, os);
		os << ")";
	}
	
public: // public function
	Treap() : root(nullptr) {}
	
	void insert(int k, T val) { root = insert(root, k, val, rnd()); }
	void erase(int k) { root = erase(root, k); }
	Node* find(int k) { return find(root, k); }
	int size() { return count(root); }
	
	void dump(ostream& os) {
		dump(root, os);
		os << endl;
	}
	
	~Treap() { while (root) erase(0); }
};

int Q, L;

void run() {
	long long base = 0;
	Treap< long long > treap;
	
	auto lowerBound = [&](long long x) {
		int lb = -1, ub = treap.size();
		while (ub - lb > 1) {
			int med = (ub + lb) / 2;
			if (treap.find(med)->val < x) lb = med;
			else ub = med;
		}
		return ub;
	};
	
	auto upperBound = [&](long long x) {
		int lb = -1, ub = treap.size();
		while (ub - lb > 1) {
			int med = (ub + lb) / 2;
			if (treap.find(med)->val <= x) lb = med;
			else ub = med;
		}
		return ub;
	};
	
	for (int i=0; i<Q; ++i) {
		int t;
		scanf("%d", &t);
		
		if (t == 0) {
			treap.insert((int)treap.size(), base + L);
		}
		
		if (t == 1) {
			int d;
			scanf("%d\n", &d);
			base += d;
			int num = upperBound(base);
			if (num > 0) printf("damage %d\n", num);
			for (int i=0; i<num; ++i) treap.erase(0);
		}
		
		if (t == 2) {
			int k;
			scanf("%d\n", &k);
			if ((int)treap.size() >= k) puts("hit");
			else puts("miss");
			treap.erase(k-1);
		}
		
		if (t == 3) {
			int x, r;
			scanf("%d %d\n", &x, &r);
			int lft = lowerBound(base + x - r), rgt = upperBound(base + x + r);
			printf("bomb %d\n", rgt - lft);
			for (int i=0; i<rgt-lft; ++i) treap.erase(lft);
		}
		
		if (t == 4) {
			int k;
			scanf("%d\n", &k);
			if ((int)treap.size() >= k) printf("distance %d\n", (int)(treap.find(k-1)->val - base));
			else puts("distance -1");
		}
	}
	
	puts("end");
}

int main() {
	while (cin >> Q >> L, Q) {
		run();
	}
}
accuracy: 1
time_ms: 120
memory_kb: 6300
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

template< typename T >
class Treap {
private: // parts
	unsigned int rnd() {
		static unsigned int x = 123456789, y = 362436069, z = 521288629, w = 88675123;
		unsigned int t = (x ^ (x << 11));
		x = y; y = z; z = w;
		return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
	}
	
	struct Node {
		T val, data, add;
		Node *lch, *rch;
		int pri, cnt;
		bool rev;
		
		Node(T v, int p) : val(v), data(v), add(T(0)), pri(p), cnt(1), rev(false) { lch = rch = nullptr; }
	};
	
	Node *root;
	
private: // main function
	int count(Node* t) { return t ? t->cnt : 0; }
	T data(Node* t) { return t ? t->data : T(1e9); }	
	
	void push(Node* t) {
		if (t && t->rev) {
			swap(t->lch, t->rch);
			if (t->lch) t->lch->rev ^= true;
			if (t->rch) t->rch->rev ^= true;
			t->rev = false;
		}
		
		if (t && t->add != 0) {
			t->val += t->add;
			if (t->lch) t->lch->add += t->add;
			if (t->rch) t->rch->add += t->add;
			t->add = 0;
		}
	}
	
	Node* update(Node *t) {
		if (!t) return t;
		t->cnt = count(t->lch) + count(t->rch) + 1;
		//t->data = calc(calc(data(t->lch), data(t->rch)), t->val);
		return t;
	}
	
	Node* merge(Node* l, Node* r) {
		push(l); push(r);
		
		if (!l || !r) return l ? l : r;
	
		if (l->pri > r->pri) {
			l->rch = merge(l->rch, r);
			return update(l);
		} else {
			r->lch = merge(l, r->lch);
			return update(r);
		}
	}
	
	typedef pair< Node*, Node* > pnn;
	
	pnn split(Node* t, int k) {
		if (!t) return pnn(nullptr, nullptr);
		
		push(t);
		
		if (k <= count(t->lch)) {
			pnn s = split(t->lch, k);
			t->lch = s.second;
			return pnn(s.first, update(t));
		} else {
			pnn s = split(t->rch, k - count(t->lch) - 1);
			t->rch = s.first;
			return pnn(update(t), s.second);
		}
	}
	
	Node* insert(Node* t, int k, T val, int pri) {
		pnn s = split(t, k);
		t = merge(s.first, new Node(val, pri));
		t = merge(t, s.second);
		return update(t);
	}
	
	Node* erase(Node* t, int k) {
		pnn s1 = split(t, k + 1);
		pnn s2 = split(s1.first, k);
		t = merge(s2.first, s1.second);
		delete s2.second;
		return update(t);
	}
	
	Node* find(Node* t, int k) {
		push(t);
		int c = count(t->lch);
		if (k < c) return find(t->lch, k);
		if (k > c) return find(t->rch, k - c - 1);
		return t;
	}
	
	void dump(Node* t, ostream& os) {
		if (!t) return;
		os << "(";
		dump(t->lch, os);
		os << t->val;
		dump(t->rch, os);
		os << ")";
	}
	
public: // public function
	Treap() : root(nullptr) {}
	
	void insert(int k, T val) { root = insert(root, k, val, rnd()); }
	void erase(int k) { root = erase(root, k); }
	Node* find(int k) { return find(root, k); }
	int size() { return count(root); }
	
	void dump(ostream& os) {
		dump(root, os);
		os << endl;
	}
	
	~Treap() { while (root) erase(0); }
};

int Q, L;

void run() {
	long long base = 0;
	Treap< long long > treap;
	
	auto lowerBound = [&](int x) {
		int lb = -1, ub = treap.size();
		while (ub - lb > 1) {
			int med = (ub + lb) / 2;
			if (treap.find(med)->val < x) lb = med;
			else ub = med;
		}
		return ub;
	};
	
	auto upperBound = [&](int x) {
		int lb = -1, ub = treap.size();
		while (ub - lb > 1) {
			int med = (ub + lb) / 2;
			if (treap.find(med)->val <= x) lb = med;
			else ub = med;
		}
		return ub;
	};
	
	for (int i=0; i<Q; ++i) {
		int t;
		scanf("%d", &t);
		
		if (t == 0) {
			treap.insert((int)treap.size(), base + L);
		}
		
		if (t == 1) {
			int d;
			scanf("%d\n", &d);
			base += d;
			int num = upperBound(base);
			if (num > 0) printf("damage %d\n", num);
			for (int i=0; i<num; ++i) treap.erase(0);
		}
		
		if (t == 2) {
			int k;
			scanf("%d\n", &k);
			if ((int)treap.size() >= k) puts("hit");
			else puts("miss");
			treap.erase(k-1);
		}
		
		if (t == 3) {
			int x, r;
			scanf("%d %d\n", &x, &r);
			int lft = lowerBound(base + x - r), rgt = upperBound(base + x + r);
			printf("bomb %d\n", rgt - lft);
			for (int i=0; i<rgt-lft; ++i) treap.erase(lft);
		}
		
		if (t == 4) {
			int k;
			scanf("%d\n", &k);
			if ((int)treap.size() >= k) printf("distance %d\n", (int)(treap.find(k-1)->val - base));
			else puts("distance -1");
		}
	}
	
	puts("end");
}

int main() {
	while (cin >> Q >> L, Q) {
		run();
	}
}
accuracy: 0.15384615384615385
time_ms: 100
memory_kb: 6300
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

template< typename T >
class Treap {
private: // parts
	unsigned int rnd() {
		static unsigned int x = 123456789, y = 362436069, z = 521288629, w = 88675123;
		unsigned int t = (x ^ (x << 11));
		x = y; y = z; z = w;
		return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
	}
	
	struct Node {
		T val, data, add;
		Node *lch, *rch;
		int pri, cnt;
		bool rev;
		
		Node(T v, int p) : val(v), data(v), add(T(0)), pri(p), cnt(1), rev(false) { lch = rch = nullptr; }
	};
	
	Node *root;
	
private: // main function
	int count(Node* t) { return t ? t->cnt : 0; }
	T data(Node* t) { return t ? t->data : T(1e9); }	
	
	void push(Node* t) {
		if (t && t->rev) {
			swap(t->lch, t->rch);
			if (t->lch) t->lch->rev ^= true;
			if (t->rch) t->rch->rev ^= true;
			t->rev = false;
		}
		
		if (t && t->add != 0) {
			t->val += t->add;
			if (t->lch) t->lch->add += t->add;
			if (t->rch) t->rch->add += t->add;
			t->add = 0;
		}
	}
	
	Node* update(Node *t) {
		if (!t) return t;
		t->cnt = count(t->lch) + count(t->rch) + 1;
		//t->data = calc(calc(data(t->lch), data(t->rch)), t->val);
		return t;
	}
	
	Node* merge(Node* l, Node* r) {
		push(l); push(r);
		
		if (!l || !r) return l ? l : r;
	
		if (l->pri > r->pri) {
			l->rch = merge(l->rch, r);
			return update(l);
		} else {
			r->lch = merge(l, r->lch);
			return update(r);
		}
	}
	
	typedef pair< Node*, Node* > pnn;
	
	pnn split(Node* t, int k) {
		if (!t) return pnn(nullptr, nullptr);
		
		push(t);
		
		if (k <= count(t->lch)) {
			pnn s = split(t->lch, k);
			t->lch = s.second;
			return pnn(s.first, update(t));
		} else {
			pnn s = split(t->rch, k - count(t->lch) - 1);
			t->rch = s.first;
			return pnn(update(t), s.second);
		}
	}
	
	Node* insert(Node* t, int k, T val, int pri) {
		pnn s = split(t, k);
		t = merge(s.first, new Node(val, pri));
		t = merge(t, s.second);
		return update(t);
	}
	
	Node* erase(Node* t, int k) {
		pnn s1 = split(t, k + 1);
		pnn s2 = split(s1.first, k);
		t = merge(s2.first, s1.second);
		delete s2.second;
		return update(t);
	}
	
	Node* find(Node* t, int k) {
		push(t);
		int c = count(t->lch);
		if (k < c) return find(t->lch, k);
		if (k > c) return find(t->rch, k - c - 1);
		return t;
	}
	
	void dump(Node* t, ostream& os) {
		if (!t) return;
		os << "(";
		dump(t->lch, os);
		os << t->val;
		dump(t->rch, os);
		os << ")";
	}
	
public: // public function
	Treap() : root(nullptr) {}
	
	void insert(int k, T val) { root = insert(root, k, val, rnd()); }
	void erase(int k) { root = erase(root, k); }
	Node* find(int k) { return find(root, k); }
	int size() { return count(root); }
	
	void dump(ostream& os) {
		dump(root, os);
		os << endl;
	}
	
	~Treap() { while (root) erase(0); }
};

int Q, L;

void run() {
	long long base = 0;
	Treap< long long > treap;
	
	auto upperBound = [&](int x) {
		int lb = -1, ub = treap.size();
		while (ub - lb > 1) {
			int med = (ub + lb) / 2;
			if (treap.find(med)->val <= x) lb = med;
			else ub = med;
		}
		return ub;
	};
	
	for (int i=0; i<Q; ++i) {
		int t;
		scanf("%d", &t);
		
		if (t == 0) {
			treap.insert((int)treap.size(), base + L);
		}
		
		if (t == 1) {
			int d;
			scanf("%d\n", &d);
			base += d;
			int num = upperBound(base);
			if (num > 0) printf("damage %d\n", num);
			for (int i=0; i<num; ++i) treap.erase(0);
		}
		
		if (t == 2) {
			int k;
			scanf("%d\n", &k);
			if ((int)treap.size() >= k) puts("hit");
			else puts("miss");
			treap.erase(k-1);
		}
		
		if (t == 3) {
			int x, r;
			scanf("%d %d\n", &x, &r);
			int lft = upperBound(base + x - r - 1), rgt = upperBound(base + x + r);
			printf("bomb %d\n", rgt - lft);
			for (int i=0; i<rgt-lft; ++i) treap.erase(lft);
		}
		
		if (t == 4) {
			int k;
			scanf("%d\n", &k);
			if ((int)treap.size() >= k) printf("distance %d\n", (int)(treap.find(k-1)->val - base));
			else puts("distance -1");
		}
	}
	
	puts("end");
}

int main() {
	while (cin >> Q >> L, Q) {
		run();
	}
}
accuracy: 0.15384615384615385
time_ms: 100
memory_kb: 6368
final_rank: 13

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r)?????´??°??????. ?????????0-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 0, int b = -1) {
		if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b <= l || r <= a) //[a,b)??¨[l,r)???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r)???[a,b)????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m, b);
		update_node(k);
	}
	//get(l,r) := [l,r)?????????????????¨?????????????????????. ?????????0-indexed.
	Value1 get(int l, int r, int k = 1, int a = 0, int b = -1) {
		if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b <= l || r <= a) //[a,b)??¨[l,r)???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r)???[a,b)????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L], cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 1, cp.mp[nowx + q.a] + 1);
				seg.update(cp.mp[nowx], cp.mp[nowx + q.a] + 1, make_pair(1, 0));
				if (damage) {
					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 1, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + 1+ amax, cp.mp[nowx] + 2+ amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(cp.mp[q.a], cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a], cp.mp[q.b] + 1, make_pair(1, 0));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 1, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[cp.mp[nowx] +1+ amax] - nowx;
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
		assert(cp.mp.size() == cp.revmp.size());
	}
	return 0;
}
accuracy: 1
time_ms: 1340
memory_kb: 31188
final_rank: 8

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 0, int b = -1) {
	if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b <= l || r <= a) //[a,b]??¨[l,r]???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m, b);
		update_node(k);
	}
	//get(l,r) := [l,r]?????????????????¨?????????????????????. ?????????1-indexed.
	Value1 get(int l, int r, int k = 1, int a = 1, int b = -1) {
	if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m + 1, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L], cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1);
				seg.update(cp.mp[nowx], cp.mp[nowx + q.a] + 1, make_pair(1, 0));
				if (damage) {
					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + 1+ amax, cp.mp[nowx] + 2+ amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(cp.mp[q.a] + 1, cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a], cp.mp[q.b] + 1, make_pair(1, 0));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[cp.mp[nowx] +1+ amax] - nowx;
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
		assert(cp.mp.size() == cp.revmp.size());
	}
	return 0;
}
accuracy: 1
time_ms: 1350
memory_kb: 31188
final_rank: 9

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a + 1);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m + 1, b);
		update_node(k);
	}
	//get(l,r) := [l,r]?????????????????¨?????????????????????. ?????????1-indexed.
	Value1 get(int l, int r, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m + 1, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L] + 1, cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1);
				seg.update(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1, make_pair(1, 0));
				if (damage) {
					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + 2+ amax, cp.mp[nowx] + 2+ amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(cp.mp[q.a] + 1, cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a] + 1, cp.mp[q.b] + 1, make_pair(1, 0));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[cp.mp[nowx] +1+ amax] - nowx;
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
		assert(cp.mp.size() == cp.revmp.size());
	}
	return 0;
}
accuracy: 1
time_ms: 1370
memory_kb: 31344
final_rank: 10

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a + 1);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m + 1, b);
		update_node(k);
	}
	//get(l,r) := [l,r]?????????????????¨?????????????????????. ?????????1-indexed.
	Value1 get(int l, int r, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m + 1, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L] + 1, cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1);
				seg.update(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1, make_pair(1, 0));
				if (damage) {
					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + 1+ amax, cp.mp[nowx] + 1+ amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(cp.mp[q.a] + 1, cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a] + 1, cp.mp[q.b] + 1, make_pair(1, -1));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[cp.mp[nowx] +1+ amax] - nowx;
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
		assert(cp.mp.size() == cp.revmp.size());
	}
	return 0;
}
accuracy: 0.15384615384615385
time_ms: 400
memory_kb: 22584
final_rank: 17

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a + 1);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m + 1, b);
		update_node(k);
	}
	//get(l,r) := [l,r]?????????????????¨?????????????????????. ?????????1-indexed.
	Value1 get(int l, int r, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m + 1, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L] + 1, cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1);
				if (damage) {

					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + 1+ amax, cp.mp[nowx] + 1+ amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(max(cp.mp[nowx]+2,cp.mp[q.a] + 1), cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a] + 1, cp.mp[q.b] + 1, make_pair(1, -1));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[cp.mp[nowx] +1+ amax] - nowx;
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
		assert(cp.mp.size() == cp.revmp.size());
	}
	return 0;
}
accuracy: 0.15384615384615385
time_ms: 330
memory_kb: 22608
final_rank: 16

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a + 1);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m + 1, b);
		update_node(k);
	}
	//get(l,r) := [l,r]?????????????????¨?????????????????????. ?????????1-indexed.
	Value1 get(int l, int r, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m + 1, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L] + 1, cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1);
				if (damage) {

					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + 1+ amax, cp.mp[nowx] + 1+ amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(cp.mp[q.a] + 1, cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a] + 1, cp.mp[q.b] + 1, make_pair(1, -1));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 2, cp.mp[nowx] + 2 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[cp.mp[nowx] +1+ amax] - nowx;
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
	}
	return 0;
}
accuracy: 0.07692307692307693
time_ms: 330
memory_kb: 22552
final_rank: 18

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a + 1);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m + 1, b);
		update_node(k);
	}
	//get(l,r) := [l,r]?????????????????¨?????????????????????. ?????????1-indexed.
	Value1 get(int l, int r, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m + 1, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			for (auto&q : qs) {
				if (q.type == 1) {
				}
				else if (q.type == 3) {
				}
			}
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L] + 1, cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1);
				if (damage) {

					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 1, cp.mp[nowx] + 1 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + amax, cp.mp[nowx] + amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(cp.mp[q.a] + 1, cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a] + 1, cp.mp[q.b] + 1, make_pair(1, -1));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 1, cp.mp[nowx] + 1 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[cp.mp[nowx] + amax] - nowx;
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
	}
	return 0;
}
accuracy: 0.07692307692307693
time_ms: 340
memory_kb: 22564
final_rank: 20

code_snippet: #include "bits/stdc++.h"
using namespace std;


typedef int Value1;
typedef pair<bool,int>Value2;
const Value1 Zero1(0);
const Value2 Zero2(make_pair(false, 0));

struct Node {
	Value1 sum;//??´??°????????????. ?????????????????§??????????????????????????¨????????????????????????????????????.
	Value2 lazy;	//?????¶???????????????????????????????????????
	Node() :sum(Zero1) {
		lazy = Zero2;
	}
};
struct lazy_segtree {
	int N;
	vector<Node>dat;
	lazy_segtree(int n) :N(1) {
		while (N < n) N *= 2;
		dat.resize(2 * N);
	}

	Value2 lazy_connect(const Value2 l, const Value2 r) {
		if (l.first || r.first)return make_pair(1, -1);
		else {
			return make_pair(0, l.second + r.second);
		}
	}

	void lazy_func(const int k, const int a, const int b) {
		if (dat[k].lazy.first)dat[k].sum = 0;
		else {
			dat[k].sum += dat[k].lazy.second*(b - a + 1);
		}
	}

	Value1 connect(const Value1 l, const Value1 r) {
		return l + r;

	}

	// inline??????????????¨??§???????????¨????????????!(??????)
	inline void lazy_evaluate_node(int k, int a, int b) {
		lazy_func(k, a, b);
		if (k < N) { // 2*k(???????????????) < 2*N (???????????°) ?????????????????§. ???????????????????????????????????¬???????????¨??????.
			dat[2 * k].lazy = lazy_connect(dat[2 * k].lazy, dat[k].lazy);	//?¬???????????????¬??????????????£?????????.
			dat[2 * k + 1].lazy = lazy_connect(dat[2 * k + 1].lazy, dat[k].lazy);
		}
		dat[k].lazy = Zero2;
	}

	inline void update_node(int k) { // k???????????¢?????????????????????????????¨?????????. ????????\????????¨????????????????????????????????????????????????????????§if???????????????.
		dat[k].sum = connect(dat[2 * k].sum, dat[2 * k + 1].sum);

	}

	// update(l,r,v) := [l,r]?????´??°??????. ?????????1-indexed.
	void update(int l, int r, Value2 v, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
		if (l < 0 || r < 0)assert(false);
		lazy_evaluate_node(k, a, b); 	// ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.

		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return;
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			dat[k].lazy = lazy_connect(dat[k].lazy, v);
			lazy_evaluate_node(k, a, b); //???????????¶???????????¨???????????¨?????????????????§.
			return;
		}

		int m = (a + b) / 2;
		update(l, r, v, 2 * k, a, m);
		update(l, r, v, 2 * k + 1, m + 1, b);
		update_node(k);
	}
	//get(l,r) := [l,r]?????????????????¨?????????????????????. ?????????1-indexed.
	Value1 get(int l, int r, int k = 1, int a = 1, int b = -1) {
		if (b == -1)b = N;
	
		if (l < 0 || r<0)assert(false);
		lazy_evaluate_node(k, a, b); // ??¨?????????????????£???????????????????????????????????§?????¬?????¨???????\?.
	
		if (b < l || r < a) //[a,b]??¨[l,r]???????????????????????´???
			return Zero1;
	
		if (l <= a && b <= r) { // [l,r]???[a,b]????????¨???????????§????????´???
			return dat[k].sum;
		}
	
		int m = (a + b) / 2;
		Value1 vl = get(l, r, 2 * k, a, m);
		Value1 vr = get(l, r, 2 * k + 1, m + 1, b);
		update_node(k);
		return connect(vl, vr);
	}
};

struct query {
	int type;
	long long int a;
	long long int b;
};
template<typename T> struct Compress {
	map<T, int>mp;
	map<int, T>revmp;

	Compress(vector<T>vs) {
		setmp(vs);
	}

	Compress() :mp(), revmp() {

	}
	void setmp(vector<T>vs) {
		sort(vs.begin(), vs.end());
		vs.erase(unique(vs.begin(), vs.end()), vs.end());
		for (int i = 0; i < static_cast<int>(vs.size()); ++i) {
			mp[vs[i]] = i;
			revmp[i] = vs[i];
		}
	}

};

int main() {
	int Q;
	while (cin>>Q,Q) {


		long long int L; cin >> L;
		Compress<long long int> cp;
		vector<query>qs;
		{

			vector<long long int>xs;
			xs.push_back(0);
			long long int nowdis = 0;
			for (int i = 0; i < Q; ++i) {
				int a; cin >> a;
				if (a == 0) {
					xs.push_back(nowdis + L);
					qs.push_back(query{ a,-1,-1 });
				}
				else if (a == 1) {
					int d; cin >> d;
					nowdis += d;
					xs.push_back(nowdis);
					qs.push_back(query{ a,d,-1 });
				}
				else if (a == 2) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
				else if (a == 3) {
					int x, r; cin >> x >> r;
					xs.push_back(nowdis + x + r);
					xs.push_back(nowdis + x - r);
					qs.push_back(query{ a,nowdis + x - r,nowdis + x + r });
				}
				else if (a == 4) {
					int k; cin >> k;
					qs.push_back(query{ a,k,-1 });
				}
			}
			cp.setmp(xs);
			for (auto&q : qs) {
				if (q.type == 1) {
				}
				else if (q.type == 3) {
				}
			}
		}
		lazy_segtree seg(cp.mp.size());
		long long int nowx = 0;
		for (auto q : qs) {
			switch (q.type) {
			case 0:
				seg.update(cp.mp[nowx + L] + 1, cp.mp[nowx + L] + 1, make_pair(0, 1));
				break;
			case 1: {

				int damage = seg.get(cp.mp[nowx] + 2, cp.mp[nowx + q.a] + 1);
				if (damage) {

					cout << "damage" << " " << damage << endl;
				}
				nowx += q.a;
			}
					break;
			case 2:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 1, cp.mp[nowx] + 1 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					cout << "hit" << endl;
					seg.update(cp.mp[nowx] + amax, cp.mp[nowx] + amax, make_pair(0, -1));
				}
				else {
					cout << "miss" << endl;
				}
			}
			break;
			case 3:
			{

				int bomb = seg.get(cp.mp[q.a] + 1, cp.mp[q.b] + 1);
				cout << "bomb " << bomb << endl;
				seg.update(cp.mp[q.a] + 1, cp.mp[q.b] + 1, make_pair(1, -1));
			}
			break;
			case 4:
			{
				int amin = -1;
				int amax = 3e5;
				while (amin + 1 != amax) {
					int amid((amin + amax) / 2);
					if (seg.get(cp.mp[nowx] + 1, cp.mp[nowx] + 1 + amid) >= q.a) {
						amax = amid;
					}
					else {
						amin = amid;
					}
				}
				if (amax != 3e5) {
					long long int dis = cp.revmp[nowx + amax] - cp.revmp[nowx];
					cout << "distance " << dis << endl;

				}
				else {
					cout << "distance -1" << endl;
				}
			}
			break;
			default:
				assert(false);
				break;
			}
		}
		cout << "end" << endl;
	}
	return 0;
}
accuracy: 0.07692307692307693
time_ms: 330
memory_kb: 22664
final_rank: 19

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<long long>H; long long q[110000], a[110000], b[110000], Q, L, S, N, bit[110000];

void add(long long x, long long r) { while (x <= N) { bit[x] += r; x += x&-x; } }
long long sum(long long r) { long long ret = 0; while (r >= 1) { ret += bit[r]; r -= r&-r; }return ret; }
int main() {
	while (true) {
		cin >> Q >> L; H.clear(); if (Q == 0 && L == 0)break; S = 0;
		for (int i = 0; i < 110000; i++)bit[i] = 0;
		for (int i = 0; i < Q; i++) {
			cin >> q[i];
			if (q[i] == 0) { H.push_back(S + L); }
			if (q[i] == 1) { cin >> a[i]; S += a[i]; }
			if (q[i] == 2) { cin >> a[i]; }
			if (q[i] == 3) { cin >> a[i] >> b[i]; }
			if (q[i] == 4) { cin >> a[i]; }
		}
		H.push_back(0); sort(H.begin(), H.end()); S = 0; N = 109500;
		for (int i = 0; i < Q; i++) {
			if (q[i] == 0) {
				int pos1 = lower_bound(H.begin(), H.end(), S + L) - H.begin();
				add(pos1, 1);
			}
			if (q[i] == 1) {
				int pos1 = lower_bound(H.begin(), H.end(), S + 1) - H.begin();
				S += a[i];
				int pos2 = lower_bound(H.begin(), H.end(), S + 1) - H.begin();
				int cnt1 = 0;
				for (int i = pos1; i < pos2; i++) {
					if (sum(i) - sum(i - 1) >= 1) {
						add(i, -1); cnt1++;
					}
				}
				if (cnt1 >= 1)cout << "damage " << cnt1 << endl;
			}
			if (q[i] == 2) {
				int L = 0, R = 109000, M;
				while (true) {
					M = (L + R) / 2;
					int pos1 = sum(M), pos2 = sum(M - 1);
					if (pos1 >= a[i] && pos2 < a[i]) { cout << "hit" << endl; add(M, -1); break; }
					if (pos1 < a[i]) {
						if (M == 108999) { cout << "miss" << endl; break; }
						else { L = M; }
					}
					if (pos2 >= a[i])R = M;
				}
			}
			if (q[i] == 3) {
				int pos1 = lower_bound(H.begin(), H.end(), S + a[i] - b[i]) - H.begin();
				int pos2 = lower_bound(H.begin(), H.end(), S + a[i] + b[i] + 1) - H.begin();
				int J = pos1 - 1; bool OK = true;
				int cnt = 0;
				while (J < pos2) {
					int L = J, R = 109000, M;
					while (true) {
						M = (L + R) / 2;
						int pos3 = sum(M) - sum(J), pos4 = sum(M - 1) - sum(J);
						if (pos3 >= 1 && pos4 < 1) {
							J = M; if (J < pos2) { cnt++; add(J, -1); } break;
						}
						if (pos3 < 1) {
							if (M == 108999) { OK = false; break; }
							else { L = M; }
						}
						if (pos4 >= 1)R = M;
					}
					if (OK == false)break;
				}
				cout << "bomb " << cnt << endl;
			}
			if (q[i] == 4) {
				int L = 0, R = 109000, M;
				while (true) {
					M = (L + R) / 2;
					int pos1 = sum(M), pos2 = sum(M - 1);
					if (pos1 >= a[i] && pos2 < a[i]) { cout << "distance " << H[M] - S << endl; break; }
					if (pos1 < a[i]) {
						if (M == 108999) { cout << "distance -1" << endl; break; }
						else { L = M; }
					}
					if (pos2 >= a[i])R = M;
				}
			}
		}
		cout << "end" << endl;
		//-------------end of the simulate------------
	}
	return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 6496
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
inline int xor128(void)
{ 
  static int x = 123456789;
  static int y = 362436069;
  static int z = 521288629;
  static int w = 88675123; 
  int t;
   
  t = x ^ (x << 11);
  x = y; y = z; z = w;
  return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}
#define int long long
struct Node
{
  int Value;
  int SubTreeSize;
  Node *Lch, *Rch;
  Node(int V):Value(V), SubTreeSize(1) {
    Lch = (Node *)NULL;
    Rch = (Node *)NULL;
  };
};
inline int Count(Node *t)
{
  if(t == (Node *)NULL) return(0);
  else return(t -> SubTreeSize);
}

inline Node *Update(Node *t)
{
  if(t == (Node *)NULL) return((Node *)NULL);
  t -> SubTreeSize = Count(t -> Lch) + Count(t -> Rch) + 1;
  return(t);
}
  
inline Node *MakeRoot(int value)
{
  return(new Node(value));
}
  
Node *Merge(Node *l, Node *r)
{
  if(l == (Node *)NULL) return(r);
  if(r == (Node *)NULL) return(l);
  int Left  = l -> SubTreeSize;
  int Right = r -> SubTreeSize;
  if(xor128() % (Left + Right) < Left) {
    l -> Rch = Merge(l -> Rch, r);
    return(Update(l));
  } else {
    r -> Lch = Merge(l, r -> Lch);
    return(Update(r));
  }
}
    
pair< Node*, Node* > Split(Node *t, int k) // [0, k), [k, n)
{
  if(t == (Node *)NULL) return(make_pair((Node *)NULL, (Node *)NULL));
  if(k <= Count(t -> Lch)) {
    pair< Node *, Node *> s = Split(t -> Lch, k);
    t -> Lch = s.second;
    return(make_pair(s.first, Update(t)));
  } else {
    pair< Node *, Node *> s = Split(t -> Rch, k - Count(t -> Lch) - 1);
    t -> Rch = s.first;
    return(make_pair(Update(t), s.second));
  }
}
  
Node *Insert(Node *root, int pos, int value)
{
  Node *p = MakeRoot(value);
  pair< Node *, Node *> s = Split(root, pos);
  return(Merge(Merge(s.first, p), s.second));
}
 
Node *Erase(Node *root, int pos)
{
  pair< Node *, Node *> s = Split(root, pos);
  pair< Node *, Node *> t = Split(s.second, 1);
  delete t.first;
  return(Merge(s.first, t.second));
}
void EraseALL(Node *root)
{
  if(root        == (Node *)NULL) return;
  if(root -> Lch != (Node *)NULL) EraseALL(root -> Lch);
  if(root -> Rch != (Node *)NULL) EraseALL(root -> Rch);
  delete root;
}

int Lower_Bound(Node *root, int Value)
{
  if(root == (Node *)NULL) return(0);
  if(Value <= root -> Value) return(Lower_Bound(root -> Lch, Value));
  return(Lower_Bound(root -> Rch, Value) + Count(root -> Lch) + 1);
}

void Dump(Node *root)
{
  Update(root);
  if(root == (Node *)NULL) return;
  cout << "(";
  Dump(root -> Lch);
  cout << "" << root -> Value << "";
  Dump(root -> Rch);
  cout << ")";
} 


signed main()
{
  int Q, L;
  Node *root = (Node *)NULL;

  while(true) {
    scanf("%lld %lld", &Q, &L);
    if(Q == 0 && L == 0) break;
    long long D = 0LL;
    while(Q--) {
      int type;
      scanf("%lld", &type);
      if(type == 0) {
        root = Insert(root, Lower_Bound(root, L + D), L + D);
      } else if(type == 1) {
        int d;
        scanf("%lld", &d);
        D += d;
        if(root != (Node *)NULL) {
          pair< Node*, Node* > S = Split(root, Lower_Bound(root, D + 1));
          if(Count(S.first) > 0) {
            printf("damage %lld\n", Count(S.first));
            EraseALL(S.first);
          }
          root = S.second;
        }
      } else if(type == 2) {
        int k;
        scanf("%lld", &k);
        if(Count(root) >= k) {
          root = Erase(root, --k);
          puts("hit");
        } else {
          puts("miss");
        }
      } else if(type == 3) {
        int x, r;
        scanf("%lld %lld", &x, &r);
        pair< Node*, Node* > S = Split(root, Lower_Bound(root, D + x - r));
        pair< Node*, Node* > T = Split(S.second, Lower_Bound(S.second, D + x + r + 1));
        printf("bomb %lld\n", Count(T.first));
        EraseALL(T.first);
        root = Merge(S.first, T.second);
      } else {
        int k;
        scanf("%lld", &k);
        int dist = -1;
        if(Count(root) >= k) {
          pair< Node*, Node* > S = Split(root, --k);
          pair< Node*, Node* > T = Split(S.second, 1);
          dist = T.first -> Value - D;
          S.second = Merge(T.first, T.second);
          root = Merge(S.first, S.second);
        }
        printf("distance %lld\n", dist);
      }
    }
    EraseALL(root);
    root = (Node *)NULL;
    puts("end");
  }
}
accuracy: 1
time_ms: 120
memory_kb: 3356
final_rank: 1