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

#define long int64_t
#define endl '\n'

#ifdef OFFLINE
	#define logan(...) logg(#__VA_ARGS__, __VA_ARGS__)
	template<class Arg>
	void logg(const char* name, Arg&& arg){ cerr << name << ": " << arg << '\n'; }
	template<class Arg, class ... Args>
	void logg(const char* name, Arg&& arg, Args&& ... args){
		char *next = (char*)name, *cand;
		int depth = 0;
		do{
			if(depth){ next = strchr(next+1, ')'); --depth; }
			else if((cand = strchr(next+1, '('))){ next = cand; ++depth; }
			else{ next = strchr(next+1, ','); }
		}while(depth);
		cerr.write(name, next-name) << ": " << arg << ",";
		logg(next+1, args...);
	}
	#define timeme 1.0*clock()/CLOCKS_PER_SEC
#else
	#define logan(...) {}
	#define timeme {}
#endif

int w, h, r, q;

struct pr{
	int a, b;
};

template<int MAXN>
struct segtr{
	//The lazy propagation updator
	struct update{
		basic_string<pr> x;
		
		update() : x(basic_string<pr>()) {}
		update(int x, int y) : x(basic_string<pr>(1, {x, y})) {}
		update& operator+= (const update& other){
			x += other.x;
			return *this;
		}
		update operator+ (const update& other){
			update tmp = *this;
			return tmp += other;
		}

		operator bool(){
			return x.length() != 0;
		}
	};
	//To change repurpose of the segtree just redefine the operators
	struct node{
		double x;
		int coord;
		update y;
		
		node(double x = 0, int coord = 0) : x(x), coord(coord) {}
		node& operator+= (const node& other){
			x += other.x;
			return *this;
		}
		node operator+ (const node& other){
			node tmp = *this;
			return tmp += other;
		}

		node& operator+= (const update& other){
			/* logic here */
			for(auto& i : other.x){
				x = min(x, i.a-sqrt(r*r - (i.a-coord)*(i.a-coord)));
			}

			return *this;
		}
	};
	
	node a[2*MAXN];
	
	//Initialize the array
	void init(){
		for(int i = 1; i <= MAXN; ++i){
			if(i <= w)
				a[i+MAXN-1] = {(double)h, i};
			else 
				a[i+MAXN-1] = node{};
		}
		for(int i = MAXN-1; i > 0; --i){
			a[i] = a[2*i] + a[2*i+1];
		}
	}
	
	//Propagate the changes
	void prop(int pos){
		if(a[pos].y){
			a[pos] += a[pos].y;
			if(pos < MAXN){
				a[2*pos].y += a[pos].y;
				a[2*pos+1].y += a[pos].y;
			}
			a[pos].y = update{};
		}
	}
	
	//Gets the range query
	node get(int l, int r, int pos = 1, int rl = 1, int rr = MAXN){
		prop(pos);
		if(r < rl || rr < l){ return node{}; }
		if(l <= rl && rr <= r){ return a[pos]; }
		
		int rm = (rl+rr)/2;
		return get(l, r, 2*pos, rl, rm) + get(l, r, 2*pos+1, rm+1, rr);
	}
	
	//Lazy updates
	void lazy(int l, int r, update val, int pos = 1, int rl = 1, int rr = MAXN){
		prop(pos);
		if(r < rl || rr < l){ return; }
		if(l <= rl && rr <= r){
			a[pos].y += val;
			prop(pos);
			return;
		}
		
		int rm = (rl+rr)/2;
		lazy(l, r, val, 2*pos, rl, rm);
		lazy(l, r, val, 2*pos+1, rm+1, rr);
		a[pos] = a[2*pos]+a[2*pos+1];
	}
	
};
segtr<8> tr;

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cerr.tie(nullptr);

	cin >> w >> h >> r >> q;
	++w;

	tr.init();

	for(;q--;){
		int cmd;
		cin >> cmd;
		--cmd;
		logan(q, cmd);
		if(cmd){
			int x;
			cin >> x;
			++x;
			cout << fixed << setprecision(20) << tr.get(x, x).x << endl;
		}else{
			int x, y;
			cin >> x >> y;
			++x;
			tr.lazy(x-(r-1), x+(r-1), {x, y});
		}
	}

}