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

using DB = double;
const DB EPS = 1e-8;
const DB PI = acos(-1);
const DB INF = 1e100;

inline DB sqr(DB x) {
	return x * x;
}

struct PT {
	DB x, y;
	PT (DB x = 0, DB y = 0) : x(x), y(y) {}
	void in() {
		scanf("%lf%lf", &x, &y);
		x /= 1000, y /= 1000;
	}
};

PT operator + (PT a, PT b) {
	return PT(a.x + b.x, a.y + b.y);
}

PT operator - (PT a, PT b) {
	return PT(a.x - b.x, a.y - b.y);
}

PT operator * (PT a, DB b) {
	return PT(a.x * b, a.y * b);
}

PT operator / (PT a, DB b) {
	return PT(a.x / b, a.y / b);
}

DB dis2(PT p) {
	return sqr(p.x) + sqr(p.y);
}

DB dis(PT p) {
	return sqrt(dis2(p));
}

DB scal(PT a, PT b) {
	return a.x * b.x + a.y * b.y;
}

DB getAngle(PT p) {
	return atan2(p.y, p.x);
}

int posCirLine(PT p, DB r, PT p1, PT p2, PT *q) {
	DB a = dis2(p1 - p2);
	DB b = scal(p - p1, p2 - p1);
	DB c = dis2(p - p1) - sqr(r);
	DB d2 = sqr(b) - a * c;
	if (d2 < -EPS) return 0;
	DB d = sqrt(fabs(d2));
	q[0] = p1 + (p2 - p1) * ((b + d) / a);
	q[1] = p1 + (p2 - p1) * ((b - d) / a);
	if (d2 < EPS) return 1;
	return 2;
}

const int N = 55000;
const int M = N + N;
PT A[N], B[N];

struct Line{
	DB a, b;
	void in() {
		scanf("%lf%lf", &a, &b);
		a /= 1000, b /= 1000;
	}
	Line (DB a = 0, DB b = 0) : a(a), b(b) {}
	PT cross(Line l) {
		if (fabs(a - l.a) < EPS) return PT(INF, INF);
		DB x = (l.b - b) / (a - l.a);
		DB y = a * x + b;
		return PT (x, y);
	}
} L[N];

int b[M];

void add(int idx, int v) {
	for (idx++; idx < M; idx += idx & -idx) b[idx] += v;
}

int get(int idx) {
	int ret = 0;
	for (idx++; idx; idx -= idx & -idx) ret += b[idx];
	return ret;
}

struct query{
	DB val;
	int id, sig;
	query(DB val = 0, int id = 0, int sig = 1) : val(val), id(id), sig(sig) {}
	bool operator <(const query &q) const {
		return val < q.val;
	}
};

int n, m;
PT P;
query VQ[M];
int to[M], id[M];
int vec[M], tmp[M];

long long can(DB r, bool CALC, DB &sum) {
	int vqn = 0;
	for (int i = 0; i < n; i++) {
		PT tem[2];
		if (posCirLine(P, r, A[i], B[i], tem)) {
			DB ang[2];
			for (int j = 0; j < 2; j++) ang[j] = getAngle(tem[j] - P);
			if (ang[1] < ang[0]) swap(ang[0], ang[1]);
			VQ[vqn++] = query(ang[0], i, 1);
			VQ[vqn++] = query(ang[1], i, -1);
		}
	}
	for (int i = 0; i < vqn; i++) id[i] = i;
	sort(id, id + vqn, [](int a, int b) { return VQ[a].val < VQ[b].val; });
	sum = 0;
	long long cnt = 0;
	memset(b, 0, sizeof b);
	int vn = 0;
	int now = 0, all = 0;
	for (int i = 0; i < vqn; i++) {
		query t = VQ[id[i]];
		if (t.sig == 1) {
			to[t.id] = now;
			add(now, 1);
			++all;
			if (CALC) vec[vn++] = t.id;
		} else {
			cnt += (all - get(to[t.id]));
			add(to[t.id], -1);
			--all;
			if (CALC) {
				int tn = 0;
				while (vn && vec[vn - 1] != t.id) {
					int a = t.id, b = vec[vn - 1];
					assert(fabs(L[a].a - L[b].a) > EPS);
					sum += dis(P - L[a].cross(L[b]));
					tmp[tn++] = b;
					vn--;
				}
				if (vn) vn--;
				while (tn) {
					vec[vn++] = tmp[tn - 1];
					--tn;
				}
			}
		}
		++now;
	}
	return cnt;
}

int main() {
//	freopen("in.txt", "r", stdin);
	scanf("%d", &n);
	P.in(); scanf("%d", &m);
	for (int i = 0; i < n; i++) {
		L[i].in();
		A[i] = PT(0, L[i].b);
		B[i] = PT(1, L[i].a + L[i].b);
	}
	DB st = 0, en = 3e9;
	DB ans;
	int now = clock();
	for (int times = 0; times < 48; times++) {
		DB md = (st + en) / 2;
		if (can(md, 0, ans) <= m) st = md;
		else en = md;
		if (clock() - now > 6 * CLOCKS_PER_SEC) {
			assert(times > 45);
		}
	}
	long long cnt = can(st, 1, ans);
	printf("%.10lf\n", ans + st * (m - cnt));
	return 0;
}


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

using DB = double;
const DB EPS = 1e-10;
const DB PI = acos(-1);

inline DB sqr(DB x) {
	return x * x;
}

struct PT {
	DB x, y;
	PT (DB x = 0, DB y = 0) : x(x), y(y) {}
	void in() {
		scanf("%lf%lf", &x, &y);
		x /= 1000, y /= 1000;
	}
};

PT operator + (PT a, PT b) {
	return PT(a.x + b.x, a.y + b.y);
}

PT operator - (PT a, PT b) {
	return PT(a.x - b.x, a.y - b.y);
}

PT operator * (PT a, DB b) {
	return PT(a.x * b, a.y * b);
}

PT operator / (PT a, DB b) {
	return PT(a.x / b, a.y / b);
}

DB dis2(PT p) {
	return sqr(p.x) + sqr(p.y);
}

DB dis(PT p) {
	return sqrt(dis2(p));
}

DB scal(PT a, PT b) {
	return a.x * b.x + a.y * b.y;
}

DB scal(PT a, PT b, PT c) {
	return scal(b - a, c - a);
}

DB getAngle(PT p) {
	return atan2(p.y, p.x);
}

int posCirLine(PT p, DB r, PT p1, PT p2, PT *q) {
	DB a, b, c, d2, d;
	a = dis2(p1 - p2);
	b = scal(p1, p, p2);
	c = dis2(p - p1) - sqr(r);
	d2 = sqr(b) - a * c;
	if (d2 < -EPS) return 0;
	d = sqrt(fabs(d2));
	q[0] = p1 + (p2 - p1) * ((b + d) / a);
	q[1] = p1 + (p2 - p1) * ((b - d) / a);
	if (d2 < EPS) return 1;
	return 2;
}

const int N = 55000;
const int M = N + N;
PT A[N], B[N];

struct Line{
	DB a, b;
	void in() {
		scanf("%lf%lf", &a, &b);
		a /= 1000, b /= 1000;
	}
	Line (DB a = 0, DB b = 0) : a(a), b(b) {}
	PT cross(Line l) {
		DB x = (l.b - b) / (a - l.a);
		DB y = a * x + b;
		return PT (x, y);
	}
} L[N];

struct bit{
	int b[M];
	void clear() {
		memset(b, 0, sizeof b);
	}
	void add(int idx, int v) {
		for (idx++; idx < M; idx += idx & -idx) b[idx] += v;
	}
	int get(int idx) {
		int ret = 0;
		for (idx++; idx; idx -= idx & -idx) ret += b[idx];
		return ret;
	}
} BIT;

struct query{
	DB val;
	int id, sig;
	query(DB val = 0, int id = 0, int sig = 1) : val(val), id(id), sig(sig) {}
	bool operator <(const query &q) const {
		return val < q.val;
	}
};

int n, m;
PT P;
vector<query> VQ;
int to[M];

long long can(DB r, bool CALC, DB &sum) {
	VQ.clear();
	for (int i = 0; i < n; i++) {
		PT tem[2];
		if (posCirLine(P, r, A[i], B[i], tem)) {
			DB ang[2];
			for (int j = 0; j < 2; j++) ang[j] = getAngle(tem[j] - P);
			if (ang[1] < ang[0]) swap(ang[0], ang[1]);
			VQ.push_back(query(ang[0], i, 1));
			VQ.push_back(query(ang[1], i, -1));
		}
	}
	sort(VQ.begin(), VQ.end());
	sum = 0;
	long long cnt = 0;
	BIT.clear();
	int now = 0, all = 0;
	vector<int> vec;
	for (auto &t : VQ) {
		if (t.sig == 1) {
			to[t.id] = now;
			BIT.add(now, 1);
			++all;
			if (CALC) vec.push_back(t.id);
		} else {
			cnt += (all - BIT.get(to[t.id]));
			BIT.add(to[t.id], -1);
			--all;
			if (CALC) {
				vector<int> tmp;
				while (vec.size() && vec.back() != t.id) {
					int a = t.id, b = vec.back();
					sum += dis(P - L[a].cross(L[b]));
					tmp.push_back(b);
					vec.pop_back();
				}
				if (vec.size()) vec.pop_back();
				reverse(tmp.begin(), tmp.end());
				vec.insert(vec.begin(), tmp.begin(), tmp.end());
			}
		}
		++now;
	}
	return cnt;
}

int main() {
//	freopen("in.txt", "r", stdin);
	scanf("%d", &n);
	P.in(); scanf("%d", &m);
	for (int i = 0; i < n; i++) {
		L[i].in();
		A[i] = PT(0, L[i].b);
		B[i] = PT(1, L[i].a + L[i].b);
	}
	DB st = 0, en = 1e10;
	DB ans;
	for (int times = 0; times < 100; times++) {
		DB md = (st + en) / 2;
		if (can(md, 0, ans) <= m) st = md;
		else en = md;
	}
	long long cnt = can(st, 1, ans);
	printf("%.10lf\n", ans + .0 * (m - cnt));
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fi first
#define se second

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return -s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 50005;
const db eps = 1e-9;
const db pi = acos(-1);

int n,m;
struct point{
	db x,y;
	point(const db x_=0,db y_=0){x=x_;y=y_;}
}st;
point Md[N];
point operator +(point a,point b){return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){return point(a.x-b.x,a.y-b.y);}
point operator *(point a,db c){return point(a.x*c,a.y*c);}
point operator /(point a,db c){return point(a.x/c,a.y/c);}
db cross(point a,point b,point c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}
db cross(point a,point b){return a.x*b.y-a.y*b.x;}
db operator *(point a,point b){return a.x*b.x+a.y*b.y;}
db getdis(point a){return sqrt(a.x*a.x+a.y*a.y);}
point getsec(db k1,db b1,db k2,db b2){
	db x=(b2-b1)/(k1-k2);
	db y=k1*x+b1;
	return point(x,y);
}
point multi(point a,point b){return (a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
struct line{
	db k,b;
	db v,dis,dv;
}l[N];
pair<int,int>pt[N];
bool bz[N];
int k;
struct keypoint{
	point u;
	int id,ty;
}key[N*2];

bool cmp(keypoint a,keypoint b){
	if (a.ty!=b.ty)return a.ty<b.ty;
	return cross(a.u,b.u)>0;
}

int gettype(point u){
	if(fabs(u.y)<eps)return u.x>0?1:2;
	return u.y>0?1:2;
}

int bittree[N*2];
int to[N*2];

struct QUERY{
	int l,r,v,nxt;
}qry[N*4];
int h[N*2],et;

void addquery(int x,int l,int r,int v){qry[++et].l=l;qry[et].r=r;qry[et].v=v;qry[et].nxt=h[x];h[x]=et;}

void add(int x){for(;x<=k;x+=x&-x)bittree[x]++;}

int query(int x){int ret=0;for(;x;x-=x&-x)ret+=bittree[x];return ret;}

LL calc(db R){
	k=0;
	fo(i,1,n){
		db v=l[i].v;
		db dis=l[i].dis;
		bz[i]=0;
		if (dis>=R*R)continue;
		bz[i]=1;
		if (fabs(l[i].k)<eps){
			db y=l[i].b;
			db x0=sqrt(R*R-y*y),x1=-x0;
			key[++k].u=point(x0,y);key[k].id=i;
			key[++k].u=point(x1,y);key[k].id=i;
			continue;
		}
		point M=Md[i];
		db len=R*R-dis;
		point direction=point(1,l[i].k)*sqrt(len/v);
		key[++k].u=M+direction;key[k].id=i;
		key[++k].u=M-direction;key[k].id=i;
	}
	fo(i,1,k)key[i].ty=gettype(key[i].u);
	sort(key+1,key+1+k,cmp);
	fo(i,1,n)pt[i]=make_pair(0,0);
	fo(i,1,k)
	if (pt[key[i].id].fi)pt[key[i].id].se=i;
	else pt[key[i].id].fi=i;
	fo(i,1,n)
	if (bz[i])to[pt[i].fi]=pt[i].se,to[pt[i].se]=pt[i].fi;
	LL ret=0;
	et=0;
	fo(i,1,k)h[i]=bittree[i]=0;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1){
			addquery(pt[i].se,1,pt[i].fi-1,1);
			addquery(pt[i].fi-1,1,pt[i].fi-1,-1);
		}
		if (pt[i].se<k){
			addquery(pt[i].se,pt[i].se+1,k,1);
			addquery(pt[i].fi-1,pt[i].se+1,k,-1);
		}
	}
	fo(i,1,k){
		add(to[i]);
		for(int p=h[i];p;p=qry[p].nxt)
		ret=ret+(query(qry[p].r)-query(qry[p].l-1))*qry[p].v;
	}
	ret/=2;
	return ret;
}

int be[N*2];
db ans;
int cnt;
struct node{
	int suf,pre;
}a[N*2];

void del(int w){
	int x=a[w].pre,y=a[w].suf;
	a[x].suf=y;
	a[y].pre=x;
}

void getans(db lim){
	calc(lim);
	fo(i,0,k)a[i].suf=i+1;
	fo(i,1,k+1)a[i].pre=i-1;
	int cnt=m;
	ans=0;
	fo(i,1,k)
	if(to[i]<i){
		int id=key[i].id;
		for(int x=a[i].pre;x!=to[i];x=a[x].pre){
			if (key[x].id!=id)cnt--,ans=ans+getdis(getsec(l[id].k,l[id].b,l[key[x].id].k,l[key[x].id].b));
		}
		del(i);
		del(to[i]);
	}
	ans=ans+lim*cnt;
	printf("%.9lf\n",ans);
}

int main(){
	n=get();
	st.x=get(),st.y=get();
	st.x/=1000,st.y/=1000;
	m=get();
	fo(i,1,n){
		l[i].k=get();l[i].b=get();
		l[i].k/=1000,l[i].b/=1000;
		l[i].b=l[i].b+l[i].k*st.x-st.y;
		l[i].v=l[i].k*l[i].k+1;
		l[i].dis=l[i].b*l[i].b/l[i].v;
		l[i].dv=sqrt(l[i].dis/l[i].v);
		point M=point(-l[i].k,1)*l[i].dv;
		if (fabs(l[i].k*M.x+l[i].b-M.y)>eps)M=M*(-1);
		Md[i]=M;
	}
	db l=0,r=1e13,ans=0;
	while((r-l)/l>eps){
		db mid=(l+r)/2;
		if (calc(mid)>=m)r=mid-eps;
		else l=mid+eps,ans=mid;
	}
	getans(ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fi first
#define se second

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return -s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 50005;
const db eps = 1e-9;
const db pi = acos(-1);

int n,m;
struct point{
	db x,y;
	point(const db x_=0,db y_=0){x=x_;y=y_;}
}a[N],st;
point Md[N];
point operator +(point a,point b){return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){return point(a.x-b.x,a.y-b.y);}
point operator *(point a,db c){return point(a.x*c,a.y*c);}
point operator /(point a,db c){return point(a.x/c,a.y/c);}
db cross(point a,point b,point c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}
db cross(point a,point b){return a.x*b.y-a.y*b.x;}
db operator *(point a,point b){return a.x*b.x+a.y*b.y;}
db getdis(point a){return sqrt(a.x*a.x+a.y*a.y);}
point getsec(db k1,db b1,db k2,db b2){
	db x=(b2-b1)/(k1-k2);
	db y=k1*x+b1;
	return point(x,y);
}
point multi(point a,point b){return (a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
struct line{
	db k,b;
	db v,dis,dv;
}l[N];
pair<int,int>pt[N];
bool bz[N];
int k;
struct keypoint{
	point u;
	int id,ty;
}key[N*2];

bool cmp(keypoint a,keypoint b){
	if (a.ty!=b.ty)return a.ty<b.ty;
	return cross(a.u,b.u)>0;
}

int gettype(point u){
	if(fabs(u.y)<eps)return u.x>0?1:2;
	return u.y>0?1:2;
}

int to[N*2];
struct node{
	int l,r,tot;
}tree[N*2*20];
int rt[N*2],tot;

void add(int &now,int qf,int l,int r,int x){
	tree[now=++tot]=tree[qf];
	tree[now].tot++;
	if (l==r)return;
	int mid=(l+r)/2;
	if (x<=mid)add(tree[now].l,tree[qf].l,l,mid,x);
	else add(tree[now].r,tree[qf].r,mid+1,r,x);
}

int bittree[N*2];

struct QUERY{
	int l,r,v,nxt;
}qry[N*4];
int h[N*2],et;

void addquery(int x,int l,int r,int v){qry[++et].l=l;qry[et].r=r;qry[et].v=v;qry[et].nxt=h[x];h[x]=et;}

void add(int x){for(;x<=k;x+=x&-x)bittree[x]++;}

int query(int x){int ret=0;for(;x;x-=x&-x)ret+=bittree[x];return ret;}

LL calc(db R){
	k=0;
	fo(i,1,n){
		db v=l[i].v;
		db dis=l[i].dis;
		bz[i]=0;
		if (dis>=R*R)continue;
		bz[i]=1;
		if (fabs(l[i].k)<eps){
			db y=l[i].b;
			db x0=sqrt(R*R-y*y),x1=-x0;
			key[++k].u=point(x0,y);key[k].id=i;
			key[++k].u=point(x1,y);key[k].id=i;
			continue;
		}
		point M=Md[i];
		db len=R*R-dis;
		point direction=point(1,l[i].k)*sqrt(len/v);
		key[++k].u=M+direction;key[k].id=i;
		key[++k].u=M-direction;key[k].id=i;
	}
	fo(i,1,k)key[i].ty=gettype(key[i].u);
	sort(key+1,key+1+k,cmp);
	fo(i,1,n)pt[i]=make_pair(0,0);
	fo(i,1,k)
	if (pt[key[i].id].fi)pt[key[i].id].se=i;
	else pt[key[i].id].fi=i;
	fo(i,1,n)
	if (bz[i])to[pt[i].fi]=pt[i].se,to[pt[i].se]=pt[i].fi;
	LL ret=0;
	et=0;
	fo(i,1,k)h[i]=bittree[i]=0;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1){
			addquery(pt[i].se,1,pt[i].fi-1,1);
			addquery(pt[i].fi-1,1,pt[i].fi-1,-1);
		}
		if (pt[i].se<k){
			addquery(pt[i].se,pt[i].se+1,k,1);
			addquery(pt[i].fi-1,pt[i].se+1,k,-1);
		}
	}
	fo(i,1,k){
		add(to[i]);
		for(int p=h[i];p;p=qry[p].nxt)
		ret=ret+(query(qry[p].r)-query(qry[p].l-1))*qry[p].v;
	}
	ret/=2;
	return ret;
}

int be[N*2];
db ans;
int cnt;

void getans(int now,int qf,int L,int R,int x,int y,int id){
	if (x<=L&&R<=y){
		if (tree[now].tot-tree[qf].tot==0)return;
		if (L==R){
			if (key[L].id>id)cnt--,ans=ans+getdis(getsec(l[id].k,l[id].b,l[key[L].id].k,l[key[L].id].b));
			return;
		}
	}
	int mid=(L+R)/2;
	if (x<=mid)getans(tree[now].l,tree[qf].l,L,mid,x,y,id);
	if (y>mid)getans(tree[now].r,tree[qf].r,mid+1,R,x,y,id);
}

void getans(db lim){
	calc(lim);
	tot=0;
	fo(i,1,k)add(rt[i],rt[i-1],1,k,to[i]);
	ans=0;
	cnt=m;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,1,pt[i].fi-1,i);
		if (pt[i].se<k)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,pt[i].se+1,k,i);
	}
	ans=ans+lim*cnt;
	printf("%.9lf\n",ans);
}

int main(){
	n=get();
	st.x=get(),st.y=get();
	st.x/=1000,st.y/=1000;
	m=get();
	fo(i,1,n){
		l[i].k=get();l[i].b=get();
		l[i].k/=1000,l[i].b/=1000;
		l[i].b=l[i].b+l[i].k*st.x-st.y;
		l[i].v=l[i].k*l[i].k+1;
		l[i].dis=l[i].b*l[i].b/l[i].v;
		l[i].dv=sqrt(l[i].dis/l[i].v);
		point M=point(-l[i].k,1)*l[i].dv;
		if (fabs(l[i].k*M.x+l[i].b-M.y)>eps)M=M*(-1);
		Md[i]=M;
	}
	db l=0,r=1e13,ans=0;
	while((r-l)/l>eps){
		db mid=(l+r)/2;
		if (calc(mid)>=m)r=mid-eps;
		else l=mid+eps,ans=mid;
	}
	getans(ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fi first
#define se second

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return -s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 50005;
const db eps = 1e-9;
const db pi = acos(-1);

int n,m;
struct point{
	db x,y;
	point(const db x_=0,db y_=0){x=x_;y=y_;}
}a[N],st;
point Md[N];
point operator +(point a,point b){return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){return point(a.x-b.x,a.y-b.y);}
point operator *(point a,db c){return point(a.x*c,a.y*c);}
point operator /(point a,db c){return point(a.x/c,a.y/c);}
db cross(point a,point b,point c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}
db cross(point a,point b){return a.x*b.y-a.y*b.x;}
db operator *(point a,point b){return a.x*b.x+a.y*b.y;}
db getdis(point a){return sqrt(a.x*a.x+a.y*a.y);}
point getsec(db k1,db b1,db k2,db b2){
	db x=(b2-b1)/(k1-k2);
	db y=k1*x+b1;
	return point(x,y);
}
point multi(point a,point b){return (a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
struct line{
	db k,b;
	db v,dis,dv;
}l[N];
pair<int,int>pt[N];
bool bz[N];
int k;
struct keypoint{
	point u;
	int id,ty;
}key[N*2];

bool cmp(keypoint a,keypoint b){
	if (a.ty!=b.ty)return a.ty<b.ty;
	return cross(a.u,b.u)>0;
}

int gettype(point u){
	if(fabs(u.y)<eps)return u.x>0?1:2;
	return u.y>0?1:2;
}

int to[N*2];
struct node{
	int l,r,tot;
}tree[N*2*20];
int rt[N*2],tot;

void add(int &now,int qf,int l,int r,int x){
	tree[now=++tot]=tree[qf];
	tree[now].tot++;
	if (l==r)return;
	int mid=(l+r)/2;
	if (x<=mid)add(tree[now].l,tree[qf].l,l,mid,x);
	else add(tree[now].r,tree[qf].r,mid+1,r,x);
}

int bittree[N*2];

struct QUERY{
	int l,r,v,nxt;
}qry[N*2];
int h[N*2],et;

void addquery(int x,int l,int r,int v){qry[++et].l=l;qry[et].r=r;qry[et].v=v;qry[et].nxt=h[x];h[x]=et;}

void add(int x){for(;x<=k;x+=x&-x)bittree[x]++;}

int query(int x){int ret=0;for(;x;x-=x&-x)ret+=bittree[x];return ret;}

LL calc(db R){
	k=0;
	fo(i,1,n){
		db v=l[i].v;
		db dis=l[i].dis;
		bz[i]=0;
		if (dis>=R*R)continue;
		bz[i]=1;
		if (fabs(l[i].k)<eps){
			db y=l[i].b;
			db x0=sqrt(R*R-y*y),x1=-x0;
			key[++k].u=point(x0,y);key[k].id=i;
			key[++k].u=point(x1,y);key[k].id=i;
			continue;
		}
		point M=Md[i];
		db len=R*R-dis;
		point direction=point(1,l[i].k)*sqrt(len/v);
		key[++k].u=M+direction;key[k].id=i;
		key[++k].u=M-direction;key[k].id=i;
	}
	fo(i,1,k)key[i].ty=gettype(key[i].u);
	sort(key+1,key+1+k,cmp);
	fo(i,1,n)pt[i]=make_pair(0,0);
	fo(i,1,k)
	if (pt[key[i].id].fi)pt[key[i].id].se=i;
	else pt[key[i].id].fi=i;
	fo(i,1,n)
	if (bz[i])to[pt[i].fi]=pt[i].se,to[pt[i].se]=pt[i].fi;
	LL ret=0;
	et=0;
	fo(i,1,k)h[i]=bittree[i]=0;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1){
			addquery(pt[i].se,1,pt[i].fi-1,1);
			addquery(pt[i].fi-1,1,pt[i].fi-1,-1);
		}
		if (pt[i].se<k){
			addquery(pt[i].se,pt[i].se+1,k,1);
			addquery(pt[i].fi-1,pt[i].se+1,k,-1);
		}
	}
	fo(i,1,k){
		add(to[i]);
		for(int p=h[i];p;p=qry[p].nxt)
		ret=ret+(query(qry[p].r)-query(qry[p].l-1))*qry[p].v;
	}
	ret/=2;
	return ret;
}

int be[N*2];
db ans;
int cnt;

void getans(int now,int qf,int L,int R,int x,int y,int id){
	if (x<=L&&R<=y){
		if (tree[now].tot-tree[qf].tot==0)return;
		if (L==R){
			if (key[L].id>id)cnt--,ans=ans+getdis(getsec(l[id].k,l[id].b,l[key[L].id].k,l[key[L].id].b));
			return;
		}
	}
	int mid=(L+R)/2;
	if (x<=mid)getans(tree[now].l,tree[qf].l,L,mid,x,y,id);
	if (y>mid)getans(tree[now].r,tree[qf].r,mid+1,R,x,y,id);
}

void getans(db lim){
	calc(lim);
	tot=0;
	fo(i,1,k)add(rt[i],rt[i-1],1,k,to[i]);
	ans=0;
	cnt=m;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,1,pt[i].fi-1,i);
		if (pt[i].se<k)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,pt[i].se+1,k,i);
	}
	ans=ans+lim*cnt;
	printf("%.9lf\n",ans);
}

int main(){
	n=get();
	st.x=get(),st.y=get();
	st.x/=1000,st.y/=1000;
	m=get();
	fo(i,1,n){
		l[i].k=get();l[i].b=get();
		l[i].k/=1000,l[i].b/=1000;
		l[i].b=l[i].b+l[i].k*st.x-st.y;
		l[i].v=l[i].k*l[i].k+1;
		l[i].dis=l[i].b*l[i].b/l[i].v;
		l[i].dv=sqrt(l[i].dis/l[i].v);
		point M=point(-l[i].k,1)*l[i].dv;
		if (fabs(l[i].k*M.x+l[i].b-M.y)>eps)M=M*(-1);
		Md[i]=M;
	}
	db l=0,r=1e13,ans=0;
	while((r-l)/l>eps){
		db mid=(l+r)/2;
		if (calc(mid)>=m)r=mid-eps;
		else l=mid+eps,ans=mid;
	}
	getans(ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fi first
#define se second

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return -s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 50005;
const db eps = 1e-9;
const db pi = acos(-1);

int n,m;
struct point{
	db x,y;
	point(const db x_=0,db y_=0){x=x_;y=y_;}
}a[N],st;
point operator +(point a,point b){return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){return point(a.x-b.x,a.y-b.y);}
point operator *(point a,db c){return point(a.x*c,a.y*c);}
point operator /(point a,db c){return point(a.x/c,a.y/c);}
db cross(point a,point b,point c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}
db cross(point a,point b){return a.x*b.y-a.y*b.x;}
db operator *(point a,point b){return a.x*b.x+a.y*b.y;}
db getdis(point a){return sqrt(a.x*a.x+a.y*a.y);}
point getsec(db k1,db b1,db k2,db b2){
	db x=(b2-b1)/(k1-k2);
	db y=k1*x+b1;
	return point(x,y);
}
point multi(point a,point b){return (a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
struct line{
	db k,b;
	db v,dis;
}l[N];
pair<int,int>pt[N];
bool bz[N];
int k;
struct keypoint{
	point u;
	int id,ty;
}key[N*2];

bool cmp(keypoint a,keypoint b){
	if (a.ty!=b.ty)return a.ty<b.ty;
	return cross(a.u,b.u)>0;
}

int gettype(point u){
	if(fabs(u.y)<eps)return u.x>0?1:2;
	return u.y>0?1:2;
}

int to[N*2];
struct node{
	int l,r,tot;
}tree[N*2*20];
int rt[N*2],tot;

void add(int &now,int qf,int l,int r,int x){
	tree[now=++tot]=tree[qf];
	tree[now].tot++;
	if (l==r)return;
	int mid=(l+r)/2;
	if (x<=mid)add(tree[now].l,tree[qf].l,l,mid,x);
	else add(tree[now].r,tree[qf].r,mid+1,r,x);
}

int query(int now,int qf,int l,int r,int x,int y){
	if (x<=l&&r<=y)return tree[now].tot-tree[qf].tot;
	int mid=(l+r)/2,ret=0;
	if (x<=mid)ret=query(tree[now].l,tree[qf].l,l,mid,x,y);
	if (y>mid)ret=ret+query(tree[now].r,tree[qf].r,mid+1,r,x,y);
	return ret;
}

LL calc(db R){
	k=0;
	fo(i,1,n){
		db v=l[i].v;
		db dis=l[i].dis;
		bz[i]=0;
		if (dis>=R*R)continue;
		bz[i]=1;
		if (fabs(l[i].k)<eps){
			db y=l[i].b;
			db x0=sqrt(R*R-y*y),x1=-x0;
			key[++k].u=point(x0,y);key[k].id=i;
			key[++k].u=point(x1,y);key[k].id=i;
			continue;
		}
		point M=point(-l[i].k,1)*sqrt(dis/v);
		if (fabs(l[i].k*M.x+l[i].b-M.y)>eps)M=M*(-1);
		db len=R*R-dis;
		point direction=point(1,l[i].k)*sqrt(len/v);
		key[++k].u=M+direction;key[k].id=i;
		key[++k].u=M-direction;key[k].id=i;
	}
	fo(i,1,k)key[i].ty=gettype(key[i].u);
	sort(key+1,key+1+k,cmp);
	fo(i,1,n)pt[i]=make_pair(0,0);
	fo(i,1,k)
	if (pt[key[i].id].fi)pt[key[i].id].se=i;
	else pt[key[i].id].fi=i;
	fo(i,1,n)
	if (bz[i])to[pt[i].fi]=pt[i].se,to[pt[i].se]=pt[i].fi;
	tot=0;
	fo(i,1,k)add(rt[i],rt[i-1],1,k,to[i]);
	LL ret=0;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1)ret=ret+query(rt[pt[i].se],rt[pt[i].fi-1],1,k,1,pt[i].fi-1);
		if (pt[i].se<k)ret=ret+query(rt[pt[i].se],rt[pt[i].fi-1],1,k,pt[i].se+1,k);
	}
	ret/=2;
	return ret;
}

int be[N*2];
db ans;
int cnt;

void getans(int now,int qf,int L,int R,int x,int y,int id){
	if (x<=L&&R<=y){
		if (tree[now].tot-tree[qf].tot==0)return;
		if (L==R){
			if (key[L].id>id)cnt--,ans=ans+getdis(getsec(l[id].k,l[id].b,l[key[L].id].k,l[key[L].id].b));
			return;
		}
	}
	int mid=(L+R)/2;
	if (x<=mid)getans(tree[now].l,tree[qf].l,L,mid,x,y,id);
	if (y>mid)getans(tree[now].r,tree[qf].r,mid+1,R,x,y,id);
}

void getans(db lim){
	calc(lim);
	ans=0;
	cnt=m;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,1,pt[i].fi-1,i);
		if (pt[i].se<k)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,pt[i].se+1,k,i);
	}
	ans=ans+lim*cnt;
	printf("%.9lf\n",ans);
}

int main(){
	n=get();
	st.x=get(),st.y=get();
	st.x/=1000,st.y/=1000;
	m=get();
	fo(i,1,n){
		l[i].k=get();l[i].b=get();
		l[i].k/=1000,l[i].b/=1000;
		l[i].b=l[i].b+l[i].k*st.x-st.y;
		l[i].v=l[i].k*l[i].k+1;
		l[i].dis=l[i].b*l[i].b/l[i].v;
	}
	db l=0,r=1e13,ans=0;
	while((r-l)/l>eps){
		db mid=(l+r)/2;
		if (calc(mid)>=m)r=mid-eps;
		else l=mid+eps,ans=mid;
	}
	getans(ans);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fi first
#define se second

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return -s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 50005;
const db eps = 1e-9;
const db pi = acos(-1);

int n,m;
struct point{
	db x,y;
	point(const db x_=0,db y_=0){x=x_;y=y_;}
}a[N],st;
point operator +(point a,point b){return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){return point(a.x-b.x,a.y-b.y);}
point operator *(point a,db c){return point(a.x*c,a.y*c);}
point operator /(point a,db c){return point(a.x/c,a.y/c);}
db cross(point a,point b,point c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}
db cross(point a,point b){return a.x*b.y-a.y*b.x;}
db operator *(point a,point b){return a.x*b.x+a.y*b.y;}
db getdis(point a){return sqrt(a.x*a.x+a.y*a.y);}
point getsec(db k1,db b1,db k2,db b2){
	db x=(b2-b1)/(k1-k2);
	db y=k1*x+b1;
	return point(x,y);
}
point multi(point a,point b){return (a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
struct line{
	db k,b;
	db v,dis;
}l[N];
pair<int,int>pt[N];
bool bz[N];
int k;
struct keypoint{
	point u;
	int id,ty;
}key[N*2];

bool cmp(keypoint a,keypoint b){
	if (a.ty!=b.ty)return a.ty<b.ty;
	return cross(a.u,b.u)>0;
}

int gettype(point u){
	if(fabs(u.y)<eps)return u.x>0?1:2;
	return u.y>0?1:2;
}

int to[N*2];
struct node{
	int l,r,tot;
}tree[N*2*20];
int rt[N*2],tot;

void add(int &now,int qf,int l,int r,int x){
	tree[now=++tot]=tree[qf];
	tree[now].tot++;
	if (l==r)return;
	int mid=(l+r)/2;
	if (x<=mid)add(tree[now].l,tree[qf].l,l,mid,x);
	else add(tree[now].r,tree[qf].r,mid+1,r,x);
}

int query(int now,int qf,int l,int r,int x,int y){
	if (x<=l&&r<=y)return tree[now].tot-tree[qf].tot;
	int mid=(l+r)/2,ret=0;
	if (x<=mid)ret=query(tree[now].l,tree[qf].l,l,mid,x,y);
	if (y>mid)ret=ret+query(tree[now].r,tree[qf].r,mid+1,r,x,y);
	return ret;
}

LL calc(db R){
	k=0;
	fo(i,1,n){
		db v=l[i].v;
		db dis=l[i].dis;
		bz[i]=0;
		if (dis>=R*R)continue;
		bz[i]=1;
		if (fabs(l[i].k)<eps){
			db y=l[i].b;
			db x0=sqrt(R*R-y*y),x1=-x0;
			key[++k].u=point(x0,y);key[k].id=i;
			key[++k].u=point(x1,y);key[k].id=i;
			continue;
		}
		point M=point(-l[i].k,1)*sqrt(dis/v);
		if (fabs(l[i].k*M.x+l[i].b-M.y)>eps)M=M*(-1);
		db len=R*R-dis;
		point direction=point(1,l[i].k)*sqrt(len/v);
		key[++k].u=M+direction;key[k].id=i;
		key[++k].u=M-direction;key[k].id=i;
	}
	fo(i,1,k)key[i].ty=gettype(key[i].u);
	sort(key+1,key+1+k,cmp);
	fo(i,1,n)pt[i]=make_pair(0,0);
	fo(i,1,k)
	if (pt[key[i].id].fi)pt[key[i].id].se=i;
	else pt[key[i].id].fi=i;
	fo(i,1,n)
	if (bz[i])to[pt[i].fi]=pt[i].se,to[pt[i].se]=pt[i].fi;
	tot=0;
	fo(i,1,k)add(rt[i],rt[i-1],1,k,to[i]);
	LL ret=0;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1)ret=ret+query(rt[pt[i].se],rt[pt[i].fi-1],1,k,1,pt[i].fi-1);
		if (pt[i].se<k)ret=ret+query(rt[pt[i].se],rt[pt[i].fi-1],1,k,pt[i].se+1,k);
		if (ret>m*2)return m*2+1;
	}
	ret/=2;
	return ret;
}

int be[N*2];
db ans;
int cnt;

void getans(int now,int qf,int L,int R,int x,int y,int id){
	if (x<=L&&R<=y){
		if (tree[now].tot-tree[qf].tot==0)return;
		if (L==R){
			if (key[L].id>id)cnt--,ans=ans+getdis(getsec(l[id].k,l[id].b,l[key[L].id].k,l[key[L].id].b));
			return;
		}
	}
	int mid=(L+R)/2;
	if (x<=mid)getans(tree[now].l,tree[qf].l,L,mid,x,y,id);
	if (y>mid)getans(tree[now].r,tree[qf].r,mid+1,R,x,y,id);
}

void getans(db lim){
	calc(lim);
	ans=0;
	cnt=m;
	fo(i,1,n)
	if (bz[i]){
		if (pt[i].fi>1)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,1,pt[i].fi-1,i);
		if (pt[i].se<k)getans(rt[pt[i].se],rt[pt[i].fi-1],1,k,pt[i].se+1,k,i);
	}
	ans=ans+lim*cnt;
	printf("%.9lf\n",ans);
}

int main(){
	n=get();
	st.x=get(),st.y=get();
	st.x/=1000,st.y/=1000;
	m=get();
	fo(i,1,n){
		l[i].k=get();l[i].b=get();
		l[i].k/=1000,l[i].b/=1000;
		l[i].b=l[i].b+l[i].k*st.x-st.y;
		l[i].v=l[i].k*l[i].k+1;
		l[i].dis=l[i].b*l[i].b/l[i].v;
	}
	db l=0,r=1e13,ans=0;
	while((r-l)/l>eps){
		db mid=(l+r)/2;
		if (calc(mid)>=m)r=mid-eps;
		else l=mid+eps,ans=mid;
	}
	getans(ans);
	return 0;
}


#include <bits/stdc++.h>

long double read() {
    int x;
    scanf("%d", &x);
    return x / 1000.0L;
}

const long double eps = 1e-9, Eps = 1e-7;
const int N = 1e5 + 5, V = 4e7 + 5;

int n, m, q, rb[N], vol, stc[V];
std::pair<int, int> p[N];
long double k, ox, oy, a[N], b[N], cx[N], cy[N];
long double ans, dis[N], s[N], t[N], tb[N];

struct FenwickTree {
    int f[N];

    void reset(int n) { memset(f, 0, (n + 1) * 4); }
    void modify(int u, int x) {
        for (int i = u; i <= m; i += i & -i) { f[i] += x; }
    }
    int query(int u) {
        int res = 0;
        for (int i = u; i >= 1; i ^= i & -i) { res += f[i]; }
        return res;
    }
    int query(int l, int r) {
        if (l >= r) { return 0; }
        return query(r) - query(l);
    }
} tr;

long double get(int i, int j) {
    long double x = (b[i] - b[j]) / (a[j] - a[i]), y = a[i] * x + b[i];
    return std::sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));
}

bool check(long double k, bool typ) {
    int res = 0; m = 0;
    for (int i = 0; i < n; i++) {
        long double x = cx[i] - ox, y = cy[i] - oy;
        if (dis[i] > k * k - eps) { continue; }
        if (std::abs(dis[i]) < eps) {
            s[i] = std::atan2(a[i], 1);
            t[i] = std::atan2(-a[i], -1);
        } else {
            long double z = std::sqrt(k * k / dis[i] - 1);
            s[i] = std::atan2(y - x * z, x + y * z);
            t[i] = std::atan2(y + x * z, x - y * z);
        }
        if (s[i] > t[i]) { std::swap(s[i], t[i]); }
        s[i] += eps; t[i] -= eps;
        tb[m++] = s[i]; tb[m++] = t[i];
    }
    std::sort(tb, tb + m);
    for (int i = 0; i < n; i++) {
        if (dis[i] > k * k - eps) { p[i] = {m, i}; continue; }
        p[i] = {std::upper_bound(tb, tb + m, s[i]) - tb - 1, i};
        rb[i] = std::upper_bound(tb, tb + m, t[i]) - tb;
    }
    std::sort(p, p + n);
    if (!typ) {
        tr.reset(m);
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            res += tr.query(p[i].first, rb[p[i].second]);
            tr.modify(rb[p[i].second], 1);
            if (res >= q) { return false; }
        }
    } else {
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            for (; vol > 0 && rb[stc[vol]] <= p[i].first; vol--);
            stc[++vol] = p[i].second;
            for (int i = vol - 1; i > 0; i--) {
                if (rb[stc[i]] > rb[stc[i + 1]]) { break; }
                double tmp = get(stc[i], stc[i + 1]);
                ans += tmp; res++;
                std::swap(stc[i], stc[i + 1]);
            }
        }
        ans += (q - res) * k;
    }
    return true;
}

int main() {
    scanf("%d", &n);
    ox = read(); oy = read(); scanf("%d", &q);
    int pass = 0;
    for (int i = 0; i < n; i++) {
        a[i] = read(); b[i] = read();
        if (std::abs(a[i]) < eps) {
            cx[i] = ox; cy[i] = b[i];
        } else {
            long double _a = -1 / a[i], _b = oy - _a * ox;
            cx[i] = (_b - b[i]) / (a[i] - _a);
            cy[i] = a[i] * cx[i] + b[i];
        }
        dis[i] = (ox - cx[i]) * (ox - cx[i]) + (oy - cy[i]) * (oy - cy[i]);
        if (dis[i] < eps) { pass++; }
    }
    if (pass * (pass - 1ll) / 2 >= k) { printf("0.000000\n"); return 0; }
    for (long double l = Eps, r = 21e8, mid; l <= r; ) {
        mid = (l + r) / 2;
        if (check(mid, false)) {
            l = mid + Eps; k = mid;
        } else {
            r = mid - Eps;
        }
    }
    check(k, true);
    printf("%.6f\n", (double) ans);
    return 0;
}


#include <bits/stdc++.h>

long double read() {
    int x;
    scanf("%d", &x);
    return x / 1000.0L;
}

const long double eps = 1e-9, Eps = 1e-7;
const int N = 1e5 + 5, V = 4e7 + 5;

int n, m, q, rb[N], vol, stc[V];
std::pair<int, int> p[N];
long double k, ox, oy, a[N], b[N], cx[N], cy[N];
long double ans, dis[N], s[N], t[N], tb[N];

struct FenwickTree {
    int f[N];

    void reset(int n) { memset(f, 0, (n + 1) * 4); }
    void modify(int u, int x) {
        for (int i = u; i <= m; i += i & -i) { f[i] += x; }
    }
    int query(int u) {
        int res = 0;
        for (int i = u; i >= 1; i ^= i & -i) { res += f[i]; }
        return res;
    }
    int query(int l, int r) {
        if (l >= r) { return 0; }
        return query(r) - query(l);
    }
} tr;

long double get(int i, int j) {
    long double x = (b[i] - b[j]) / (a[j] - a[i]), y = a[i] * x + b[i];
    return std::sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));
}

bool check(long double k, bool typ) {
    int res = 0; m = 0;
    for (int i = 0; i < n; i++) {
        long double x = cx[i] - ox, y = cy[i] - oy;
        if (dis[i] > k * k - eps) { continue; }
        if (std::abs(dis[i]) < eps) {
            s[i] = std::atan2(a[i], 1);
            t[i] = std::atan2(-a[i], -1);
        } else {
            long double z = std::sqrt(k * k / dis[i] - 1);
            s[i] = std::atan2(y - x * z, x + y * z);
            t[i] = std::atan2(y + x * z, x - y * z);
        }
        if (s[i] > t[i]) { std::swap(s[i], t[i]); }
        s[i] += eps; t[i] -= eps;
        tb[m++] = s[i]; tb[m++] = t[i];
    }
    std::sort(tb, tb + m);
    for (int i = 0; i < n; i++) {
        if (dis[i] > k * k - eps) { p[i] = {m, i}; continue; }
        p[i] = {std::upper_bound(tb, tb + m, s[i]) - tb - 1, i};
        rb[i] = std::upper_bound(tb, tb + m, t[i]) - tb;
    }
    std::sort(p, p + n);
    if (!typ) {
        tr.reset(m);
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            res += tr.query(p[i].first, rb[p[i].second]);
            tr.modify(rb[p[i].second], 1);
            if (res >= q) { return false; }
        }
    } else {
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            for (; vol > 0 && rb[stc[vol]] <= p[i].first; vol--);
            stc[++vol] = p[i].second;
            for (int i = vol - 1; i > 0; i--) {
                if (rb[stc[i]] > rb[stc[i + 1]]) { break; }
                double tmp = get(stc[i], stc[i + 1]);
                ans += tmp; res++;
                std::swap(stc[i], stc[i + 1]);
            }
        }
        ans += (q - res) * k;
    }
    return true;
}

int main() {
    scanf("%d", &n);
    ox = read(); oy = read(); scanf("%d", &q);
    int pass = 0;
    for (int i = 0; i < n; i++) {
        a[i] = read(); b[i] = read();
        if (std::abs(a[i]) < eps) {
            cx[i] = ox; cy[i] = b[i];
        } else {
            long double _a = -1 / a[i], _b = oy - _a * ox;
            cx[i] = (_b - b[i]) / (a[i] - _a);
            cy[i] = a[i] * cx[i] + b[i];
        }
        dis[i] = (ox - cx[i]) * (ox - cx[i]) + (oy - cy[i]) * (oy - cy[i]);
        if (dis[i] < eps) { pass++; }
    }
    if (pass * (pass - 1ll) / 2 >= q) { printf("0.000000\n"); return 0; }
    for (long double l = Eps, r = 21e8, mid; l <= r; ) {
        mid = (l + r) / 2;
        if (check(mid, false)) {
            l = mid + Eps; k = mid;
        } else {
            r = mid - Eps;
        }
    }
    check(k, true);
    printf("%.6f\n", (double) ans);
    return 0;
}


#include <bits/stdc++.h>

long double read() {
    int x;
    scanf("%d", &x);
    return x / 1000.0L;
}

const long double eps = 1e-9, Eps = 1e-7;
const int N = 1e5 + 5;

int n, m, q, rb[N];
std::pair<int, int> p[N];
std::set<std::pair<int, int>> set;
long double k, ox, oy, a[N], b[N], cx[N], cy[N];
long double ans, dis[N], s[N], t[N], tb[N];

struct FenwickTree {
    int f[N];

    void reset(int n) { memset(f, 0, (n + 1) * 4); }
    void modify(int u, int x) {
        for (int i = u; i <= m; i += i & -i) { f[i] += x; }
    }
    int query(int u) {
        int res = 0;
        for (int i = u; i >= 1; i ^= i & -i) { res += f[i]; }
        return res;
    }
    int query(int l, int r) {
        if (l >= r) { return 0; }
        return query(r) - query(l);
    }
} tr;

long double get(int i, int j) {
    long double x = (b[i] - b[j]) / (a[j] - a[i]), y = a[i] * x + b[i];
    return std::sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));
}

bool check(long double k, bool typ) {
    int res = 0; m = 0;
    for (int i = 0; i < n; i++) {
        long double x = cx[i] - ox, y = cy[i] - oy;
        if (dis[i] > k * k - eps) { continue; }
        if (std::abs(dis[i]) < eps) {
            s[i] = std::atan2(a[i], 1);
            t[i] = std::atan2(-a[i], -1);
        } else {
            long double z = std::sqrt(k * k / dis[i] - 1);
            s[i] = std::atan2(y - x * z, x + y * z);
            t[i] = std::atan2(y + x * z, x - y * z);
        }
        if (s[i] > t[i]) { std::swap(s[i], t[i]); }
        s[i] += eps; t[i] -= eps;
        tb[m++] = s[i]; tb[m++] = t[i];
    }
    std::sort(tb, tb + m);
    for (int i = 0; i < n; i++) {
        if (dis[i] > k * k - eps) { p[i] = {m, i}; continue; }
        p[i] = {std::upper_bound(tb, tb + m, s[i]) - tb - 1, i};
        rb[i] = std::upper_bound(tb, tb + m, t[i]) - tb;
    }
    std::sort(p, p + n);
    if (!typ) {
        tr.reset(m);
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            res += tr.query(p[i].first, rb[p[i].second]);
            tr.modify(rb[p[i].second], 1);
            if (res >= q) { return false; }
        }
    } else {
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            auto it = set.insert({rb[p[i].second], p[i].second}).first;
            while (it != set.begin()) {
                it--;
                if (it->first <= p[i].first) { break; }
                double tmp = get(it->second, p[i].second);
                if (tmp < k - Eps * 10) { res++; ans += tmp; }
            }
        }
        ans += (q - res) * k;
    }
    return true;
}

int main() {
    scanf("%d", &n);
    ox = read(); oy = read(); scanf("%d", &q);
    for (int i = 0; i < n; i++) {
        a[i] = read(); b[i] = read();
        if (std::abs(a[i]) < eps) {
            cx[i] = ox; cy[i] = b[i];
        } else {
            long double _a = -1 / a[i], _b = oy - _a * ox;
            cx[i] = (_b - b[i]) / (a[i] - _a);
            cy[i] = a[i] * cx[i] + b[i];
        }
        dis[i] = (ox - cx[i]) * (ox - cx[i]) + (oy - cy[i]) * (oy - cy[i]);
    }
    for (long double l = Eps, r = 21e8, mid; l <= r; ) {
        mid = (l + r) / 2;
        if (check(mid, false)) {
            l = mid + Eps; k = mid;
        } else {
            r = mid - Eps;
        }
    }
    check(k + Eps * 5, true);
    printf("%.6f\n", (double) ans);
    return 0;
}


#include <bits/stdc++.h>

long double read() {
    int x;
    scanf("%d", &x);
    return x / 1000.0L;
}

const long double eps = 1e-9, Eps = 1e-7;
const int N = 1e5 + 5, V = 4e7 + 5;

int n, m, q, rb[N], vol, stc[V];
std::pair<int, int> p[N];
long double k, ox, oy, a[N], b[N], cx[N], cy[N];
long double ans, dis[N], s[N], t[N], tb[N];

struct FenwickTree {
    int f[N];

    void reset(int n) { memset(f, 0, (n + 1) * 4); }
    void modify(int u, int x) {
        for (int i = u; i <= m; i += i & -i) { f[i] += x; }
    }
    int query(int u) {
        int res = 0;
        for (int i = u; i >= 1; i ^= i & -i) { res += f[i]; }
        return res;
    }
    int query(int l, int r) {
        if (l >= r) { return 0; }
        return query(r) - query(l);
    }
} tr;

long double get(int i, int j) {
    long double x = (b[i] - b[j]) / (a[j] - a[i]), y = a[i] * x + b[i];
    return std::sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));
}

bool check(long double k, bool typ) {
    int res = 0; m = 0;
    for (int i = 0; i < n; i++) {
        long double x = cx[i] - ox, y = cy[i] - oy;
        if (dis[i] > k * k - eps) { continue; }
        if (std::abs(dis[i]) < eps) {
            s[i] = std::atan2(a[i], 1);
            t[i] = std::atan2(-a[i], -1);
        } else {
            long double z = std::sqrt(k * k / dis[i] - 1);
            s[i] = std::atan2(y - x * z, x + y * z);
            t[i] = std::atan2(y + x * z, x - y * z);
        }
        if (s[i] > t[i]) { std::swap(s[i], t[i]); }
        s[i] += eps; t[i] -= eps;
        tb[m++] = s[i]; tb[m++] = t[i];
    }
    std::sort(tb, tb + m);
    for (int i = 0; i < n; i++) {
        if (dis[i] > k * k - eps) { p[i] = {m, i}; continue; }
        p[i] = {std::upper_bound(tb, tb + m, s[i]) - tb - 1, i};
        rb[i] = std::upper_bound(tb, tb + m, t[i]) - tb;
    }
    std::sort(p, p + n);
    if (!typ) {
        tr.reset(m);
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            res += tr.query(p[i].first, rb[p[i].second]);
            tr.modify(rb[p[i].second], 1);
            if (res >= q) { return false; }
        }
    } else {
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            for (; vol > 0 && rb[stc[vol]] <= p[i].first; vol--);
            stc[++vol] = p[i].second;
            for (int i = vol - 1; i > 0; i--) {
                if (rb[stc[i]] > rb[stc[i + 1]]) { break; }
                double tmp = get(stc[i], stc[i + 1]);
                if (tmp < k - Eps * 10) { res++; ans += tmp; }
                std::swap(stc[i], stc[i + 1]);
            }
        }
        ans += (q - res) * k;
    }
    return true;
}

int main() {
    scanf("%d", &n);
    ox = read(); oy = read(); scanf("%d", &q);
    for (int i = 0; i < n; i++) {
        a[i] = read(); b[i] = read();
        if (std::abs(a[i]) < eps) {
            cx[i] = ox; cy[i] = b[i];
        } else {
            long double _a = -1 / a[i], _b = oy - _a * ox;
            cx[i] = (_b - b[i]) / (a[i] - _a);
            cy[i] = a[i] * cx[i] + b[i];
        }
        dis[i] = (ox - cx[i]) * (ox - cx[i]) + (oy - cy[i]) * (oy - cy[i]);
    }
    for (long double l = Eps, r = 21e8, mid; l <= r; ) {
        mid = (l + r) / 2;
        if (check(mid, false)) {
            l = mid + Eps; k = mid;
        } else {
            r = mid - Eps;
        }
    }
    check(k + Eps * 5, true);
    printf("%.6f\n", (double) ans);
    return 0;
}


#include <bits/stdc++.h>

long double read() {
    int x;
    scanf("%d", &x);
    return x / 1000.0L;
}

const long double eps = 1e-9, Eps = 1e-7;
const int N = 1e5 + 5;

int n, m, q, rb[N];
std::vector<int> f;
std::pair<int, int> p[N];
long double k, ox, oy, a[N], b[N], cx[N], cy[N];
long double ans, dis[N], s[N], t[N], tb[N];

struct FenwickTree {
    int f[N];

    void reset(int n) { memset(f, 0, (n + 1) * 4); }
    void modify(int u, int x) {
        for (int i = u; i <= m; i += i & -i) { f[i] += x; }
    }
    int query(int u) {
        int res = 0;
        for (int i = u; i >= 1; i ^= i & -i) { res += f[i]; }
        return res;
    }
    int query(int l, int r) {
        if (l >= r) { return 0; }
        return query(r) - query(l);
    }
} tr;

long double get(int i, int j) {
    long double x = (b[i] - b[j]) / (a[j] - a[i]), y = a[i] * x + b[i];
    return std::sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));
}

bool check(long double k, bool typ) {
    int res = 0; m = 0;
    for (int i = 0; i < n; i++) {
        long double x = cx[i] - ox, y = cy[i] - oy;
        if (dis[i] > k * k - eps) { continue; }
        if (std::abs(dis[i]) < eps) {
            s[i] = std::atan2(a[i], 1);
            t[i] = std::atan2(-a[i], -1);
        } else {
            long double z = std::sqrt(k * k / dis[i] - 1);
            s[i] = std::atan2(y - x * z, x + y * z);
            t[i] = std::atan2(y + x * z, x - y * z);
        }
        if (s[i] > t[i]) { std::swap(s[i], t[i]); }
        s[i] += eps; t[i] -= eps;
        tb[m++] = s[i]; tb[m++] = t[i];
    }
    std::sort(tb, tb + m);
    for (int i = 0; i < n; i++) {
        if (dis[i] > k * k - eps) { p[i] = {m, i}; continue; }
        p[i] = {std::upper_bound(tb, tb + m, s[i]) - tb - 1, i};
        rb[i] = std::upper_bound(tb, tb + m, t[i]) - tb;
    }
    std::sort(p, p + n);
    if (!typ) {
        tr.reset(m);
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            res += tr.query(p[i].first, rb[p[i].second]);
            tr.modify(rb[p[i].second], 1);
            if (res >= q) { return false; }
        }
    } else {
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            for (; !f.empty() && rb[f.back()] <= p[i].first; f.pop_back());
            f.push_back(p[i].second);
            for (int i = (int) f.size() - 2; i >= 0; i--) {
                if (rb[f[i]] >= rb[f[i + 1]]) { break; }
                double tmp = get(f[i], f[i + 1]);
                if (tmp < k - Eps * 10) { res++; ans += tmp; }
                std::swap(f[i], f[i + 1]);
            }
        }
        ans += (q - res) * k;
    }
    return true;
}

int main() {
    scanf("%d", &n);
    ox = read(); oy = read(); scanf("%d", &q);
    for (int i = 0; i < n; i++) {
        a[i] = read(); b[i] = read();
        if (std::abs(a[i]) < eps) {
            cx[i] = ox; cy[i] = b[i];
        } else {
            long double _a = -1 / a[i], _b = oy - _a * ox;
            cx[i] = (_b - b[i]) / (a[i] - _a);
            cy[i] = a[i] * cx[i] + b[i];
        }
        dis[i] = (ox - cx[i]) * (ox - cx[i]) + (oy - cy[i]) * (oy - cy[i]);
    } int fuck = 0;
    for (long double l = Eps, r = 21e8, mid; l <= r; ) {
        mid = (l + r) / 2;
        if (check(mid, false)) {
            l = mid + Eps; k = mid;
        } else {
            r = mid - Eps;
        }
    }
    fprintf(stderr, "test\n");
    check(k + Eps * 5, true);
    printf("%.6f\n", (double) ans);
    return 0;
}


#include <bits/stdc++.h>

long double read() {
    int x;
    scanf("%d", &x);
    return x / 1000.0L;
}

const long double eps = 1e-9, Eps = 1e-7;
const int N = 1e5 + 5;

int n, m, q, rb[N];
std::vector<int> f;
std::pair<int, int> p[N];
long double k, ox, oy, a[N], b[N], cx[N], cy[N];
long double ans, dis[N], s[N], t[N], tb[N];

struct FenwickTree {
    int f[N];

    void reset(int n) { memset(f, 0, (n + 1) * 4); }
    void modify(int u, int x) {
        for (int i = u; i <= m; i += i & -i) { f[i] += x; }
    }
    int query(int u) {
        int res = 0;
        for (int i = u; i >= 1; i ^= i & -i) { res += f[i]; }
        return res;
    }
    int query(int l, int r) {
        if (l >= r) { return 0; }
        return query(r) - query(l);
    }
} tr;

long double get(int i, int j) {
    long double x = (b[i] - b[j]) / (a[j] - a[i]), y = a[i] * x + b[i];
    return std::sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));
}

bool check(long double k, bool typ) {
    int res = 0; m = 0;
    for (int i = 0; i < n; i++) {
        long double x = cx[i] - ox, y = cy[i] - oy;
        if (dis[i] > k * k - eps) { continue; }
        if (std::abs(dis[i]) < eps) {
            s[i] = std::atan2(a[i], 1);
            t[i] = std::atan2(-a[i], -1);
        } else {
            long double z = std::sqrt(k * k / dis[i] - 1);
            s[i] = std::atan2(y - x * z, x + y * z);
            t[i] = std::atan2(y + x * z, x - y * z);
        }
        if (s[i] > t[i]) { std::swap(s[i], t[i]); }
        s[i] += eps; t[i] -= eps;
        tb[m++] = s[i]; tb[m++] = t[i];
    }
    std::sort(tb, tb + m);
    for (int i = 0; i < n; i++) {
        if (dis[i] > k * k - eps) { p[i] = {m, i}; continue; }
        p[i] = {std::upper_bound(tb, tb + m, s[i]) - tb - 1, i};
        rb[i] = std::upper_bound(tb, tb + m, t[i]) - tb;
    }
    std::sort(p, p + n);
    if (!typ) {
        tr.reset(m);
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            res += tr.query(p[i].first, rb[p[i].second]);
            tr.modify(rb[p[i].second], 1);
            if (res >= q) { return false; }
        }
    } else {
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            for (; !f.empty() && rb[f.back()] <= p[i].first; f.pop_back());
            f.push_back(p[i].second);
            for (int i = (int) f.size() - 2; i >= 0; i--) {
                if (rb[f[i]] > rb[f[i + 1]]) { break; }
                double tmp = get(f[i], f[i + 1]);
                if (tmp < k - Eps * 10) { res++; ans += tmp; }
                std::swap(f[i], f[i + 1]);
            }
        }
        ans += (q - res) * k;
    }
    return true;
}

int main() {
    scanf("%d", &n);
    ox = read(); oy = read(); scanf("%d", &q);
    for (int i = 0; i < n; i++) {
        a[i] = read(); b[i] = read();
        if (std::abs(a[i]) < eps) {
            cx[i] = ox; cy[i] = b[i];
        } else {
            long double _a = -1 / a[i], _b = oy - _a * ox;
            cx[i] = (_b - b[i]) / (a[i] - _a);
            cy[i] = a[i] * cx[i] + b[i];
        }
        dis[i] = (ox - cx[i]) * (ox - cx[i]) + (oy - cy[i]) * (oy - cy[i]);
    }
    for (long double l = Eps, r = 21e8, mid; l <= r; ) {
        mid = (l + r) / 2;
        if (check(mid, false)) {
            l = mid + Eps; k = mid;
        } else {
            r = mid - Eps;
        }
    }
    check(k + Eps * 5, true);
    printf("%.6f\n", (double) ans);
    return 0;
}


#include <bits/stdc++.h>

long double read() {
    int x;
    scanf("%d", &x);
    return x / 1000.0L;
}

const long double eps = 1e-9, Eps = 1e-7;
const int N = 1e5 + 5, V = 4e7 + 5;

int n, m, q, rb[N], vol, stc[V];
std::pair<int, int> p[N];
long double k, ox, oy, a[N], b[N], cx[N], cy[N];
long double ans, dis[N], s[N], t[N], tb[N];

struct FenwickTree {
    int f[N];

    void reset(int n) { memset(f, 0, (n + 1) * 4); }
    void modify(int u, int x) {
        for (int i = u; i <= m; i += i & -i) { f[i] += x; }
    }
    int query(int u) {
        int res = 0;
        for (int i = u; i >= 1; i ^= i & -i) { res += f[i]; }
        return res;
    }
    int query(int l, int r) {
        if (l >= r) { return 0; }
        return query(r) - query(l);
    }
} tr;

long double get(int i, int j) {
    long double x = (b[i] - b[j]) / (a[j] - a[i]), y = a[i] * x + b[i];
    return std::sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));
}

bool check(long double k, bool typ) {
    int res = 0; m = 0;
    for (int i = 0; i < n; i++) {
        long double x = cx[i] - ox, y = cy[i] - oy;
        if (dis[i] > k * k - eps) { continue; }
        if (std::abs(dis[i]) < eps) {
            s[i] = std::atan2(a[i], 1);
            t[i] = std::atan2(-a[i], -1);
        } else {
            long double z = std::sqrt(k * k / dis[i] - 1);
            s[i] = std::atan2(y - x * z, x + y * z);
            t[i] = std::atan2(y + x * z, x - y * z);
        }
        if (s[i] > t[i]) { std::swap(s[i], t[i]); }
        s[i] += eps; t[i] -= eps;
        tb[m++] = s[i]; tb[m++] = t[i];
    }
    std::sort(tb, tb + m);
    for (int i = 0; i < n; i++) {
        if (dis[i] > k * k - eps) { p[i] = {m, i}; continue; }
        p[i] = {std::upper_bound(tb, tb + m, s[i]) - tb - 1, i};
        rb[i] = std::upper_bound(tb, tb + m, t[i]) - tb;
    }
    std::sort(p, p + n);
    if (!typ) {
        tr.reset(m);
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            res += tr.query(p[i].first, rb[p[i].second]);
            tr.modify(rb[p[i].second], 1);
            if (res >= q) { return false; }
        }
    } else {
        for (int i = 0; i < n; i++) {
            if (p[i].first == m) { break; }
            for (; vol > 0 && rb[stc[vol]] <= p[i].first; vol--);
            stc[++vol] = p[i].second;
            for (int i = vol - 1; i > 0; i--) {
                if (rb[stc[i]] > rb[stc[i + 1]]) { break; }
                double tmp = get(stc[i], stc[i + 1]);
                ans += tmp; res++;
                std::swap(stc[i], stc[i + 1]);
            }
        }
        ans += (q - res) * k;
    }
    return true;
}

int main() {
    scanf("%d", &n);
    ox = read(); oy = read(); scanf("%d", &q);
    for (int i = 0; i < n; i++) {
        a[i] = read(); b[i] = read();
        if (std::abs(a[i]) < eps) {
            cx[i] = ox; cy[i] = b[i];
        } else {
            long double _a = -1 / a[i], _b = oy - _a * ox;
            cx[i] = (_b - b[i]) / (a[i] - _a);
            cy[i] = a[i] * cx[i] + b[i];
        }
        dis[i] = (ox - cx[i]) * (ox - cx[i]) + (oy - cy[i]) * (oy - cy[i]);
    }
    for (long double l = Eps, r = 21e8, mid; l <= r; ) {
        mid = (l + r) / 2;
        if (check(mid, false)) {
            l = mid + Eps; k = mid;
        } else {
            r = mid - Eps;
        }
    }
    check(k, true);
    printf("%.6f\n", (double) ans);
    return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50000;
const long double PI=acosl(-1);
int n, size, l[N], r[N], bit[2*N], prev[2*N], next[2*N];
long double a[N], b[N];
std::pair<long double, int> event[2*N];
void extract(long double d) {
	size=0;
	for(int i=0; i<n; ++i) {
		long double A=a[i]*a[i]+1, B=-a[i]*b[i], Delta=B*B-A*(b[i]*b[i]-d*d);
		if(Delta<0) continue;
		long double x1=(-a[i]*b[i]-sqrtl(Delta))/A, x2=(-a[i]*b[i]+sqrtl(Delta))/A;
		event[size++]={atan2l(a[i]*x1+b[i], x1), i};
		event[size++]={atan2l(a[i]*x2+b[i], x2), i};
	}
	std::sort(event, event+size);
	memset(l, -1, n*sizeof(int));
	memset(r, -1, n*sizeof(int));
	for(int i=0; i<size; ++i) {
		int id=event[i].second;
		id[l[id]==-1?l:r]=i;
	}
}
long long query(int x) {
	long long s=0;
	for(; x; x&=x-1) s+=bit[x];
	return s;
}
void increase(int x) {
	for(; x<size; x+=x&-x) ++bit[x];
}
long long solve() {
	long long tot=0;
	memset(bit, 0, size*sizeof(int));
	for(int id=0; id<size; ++id) {
		int i=event[id].second;
		if(r[i]==id) continue;
		tot+=query(r[i])-query(l[i]);
		increase(r[i]);
	}
	return tot;
}
int main() {
	int m;
	long long tot;
	long double p, q, ans=0;
	std::set<int> cur;
	std::cin>>n>>p>>q>>m;
	for(int i=0; i<n; ++i) {
		std::cin>>a[i]>>b[i];
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=1e10; q-p>1e-10; ) {
		int cnt=0;
		long double d=(p+q)/2;
		extract(d);
		long long tot=solve();
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	extract(p);
	if(solve()>m) {
		puts("0");
		return 0;
	}
	for(int i=1; i<size; ++i) prev[i]=i-1, next[i-1]=i;
	prev[0]=size-1, next[size-1]=0;
	for(int id=size; id--; ) {
		int i=event[id].second, L=l[i], R=r[i];
		if(id==R) continue;
		for(int it=L; (it=next[it])!=R; ) {
			int j=event[it].second;
			long double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
			ans+=sqrtl(x*x+y*y);
			--m;
		}
		prev[next[L]]=prev[L], next[prev[L]]=next[L];
		prev[next[R]]=prev[R], next[prev[R]]=next[R];
	}
	std::cout<<std::fixed<<std::setprecision(9)<<(ans+m*p)<<std::endl;
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50001;
const double PI=acos(-1);
int n;
double a[N], b[N];
std::vector<std::pair<double, int>> event;
void proccess(double d) {
	event.clear();
	for(int i=1; i<=n; ++i) {
		double A=a[i]*a[i]+1, Delta=a[i]*b[i]-A*(b[i]*b[i]-d*d);
		if(Delta<0) continue;
		double x1=(-a[i]*b[i]-sqrt(Delta))/A, x2=(-a[i]*b[i]+sqrt(Delta))/A, alp=atan2(a[i]*x1+b[i], x1), bet=atan2(a[i]*x2+b[i], x2);
		if(alp>bet) std::swap(alp, bet);
		event.emplace_back(alp, -i);
		event.emplace_back(bet, i);
	}
	std::sort(event.begin(), event.end());
}
int main() {
	int m;
	double p, q, ans=0;
	std::set<int> cur;
	assert(scanf("%d%lf%lf%d", &n, &p, &q, &m)==4);
	for(int i=1; i<=n; ++i) {
		assert(scanf("%lf%lf", a+i, b+i)==2);
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=3e6; q-p>1e-9; ) {
		int cnt=0;
		double d=(p+q)/2;
		long long tot=0;
		proccess(d);
		for(auto e: event) if(e.second<0) tot+=cnt++; else --cnt;
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	proccess(p);
	for(auto e: event) {
		if(e.second<0) {
			int i=-e.second;
			for(int j: cur) {
				double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
				ans+=sqrt(x*x+y*y);
				--m;
			}
			cur.insert(i);
		} else cur.erase(e.second);
	}
	printf("%.10f\n", ans+m*p);
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50001;
const long double PI=acosl(-1);
int n;
bool vis[N];
long double a[N], b[N];
std::vector<std::pair<long double, int>> event;
void extract(long double d) {
	event.clear();
	for(int i=1; i<=n; ++i) {
		long double A=a[i]*a[i]+1, B=-a[i]*b[i], Delta=B*B-A*(b[i]*b[i]-d*d);
		if(Delta<0) continue;
		long double x1=(-a[i]*b[i]-sqrtl(Delta))/A, x2=(-a[i]*b[i]+sqrtl(Delta))/A;
		event.emplace_back(atan2l(a[i]*x1+b[i], x1), i);
		event.emplace_back(atan2l(a[i]*x2+b[i], x2), i);
	}
	std::sort(event.begin(), event.end());
}
int main() {
	int m;
	long double p, q, ans=0;
	std::set<int> cur;
	std::cin>>n>>p>>q>>m;
	for(int i=1; i<=n; ++i) {
		std::cin>>a[i]>>b[i];
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=3e6; q-p>1e-9; ) {
		int cnt=0;
		long double d=(p+q)/2;
		long long tot=0;
		extract(d);
		for(auto e: event) {
			int i=e.second;
			if(vis[i]^=1) tot+=cnt++; else --cnt;
		}
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	for(auto e: event) {
		int i=e.second;
		if(vis[i]^=1) {
			for(int j: cur) {
				long double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
				ans+=sqrtl(x*x+y*y);
				--m;
			}
			cur.insert(i);
		} else cur.erase(i);
	}
	std::cout<<std::fixed<<std::setprecision(9)<<(ans+m*p)<<std::endl;
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50000;
const double PI=acos(-1);
int n;
double a[N], b[N];
long long tot;
std::vector<std::pair<double, int>> event;
void proccess(double d) {
	event.clear();
	for(int i=0; i<n; ++i) {
		double ration=b[i]/sqrt(a[i]*a[i]+1)/d;
		if(abs(ration)>1) continue;
		double ave=atan2(1, -a[i]), delta=acos(ration);
		if(ave<0) ave+=PI;
		double alp=ave-delta, bet=ave+delta;
		if(alp<=-PI) alp+=2*PI;
		if(bet>PI) bet-=2*PI;
		if(alp>bet) std::swap(alp, bet);
		event.emplace_back(alp, -i-1);
		event.emplace_back(bet, i+1);
	}
	std::sort(event.begin(), event.end());
	tot=0;
	for(int i=0, cnt=0; i<event.size(); ++i) if(event[i].second<0) tot+=cnt++; else --cnt;
}
int main() {
	int m;
	double p, q, ans=0;
	std::set<int> cur;
	assert(scanf("%d%lf%lf%d", &n, &p, &q, &m)==4);
	for(int i=0; i<n; ++i) {
		assert(scanf("%lf%lf", a+i, b+i)==2);
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=3e6; q-p>1e-9; ) {
		double d=(p+q)/2;
		proccess(d);
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	proccess(p);
	for(auto e: event) {
		if(e.second<0) {
			int i=-e.second-1;
			for(int j: cur) {
				double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
				ans+=sqrt(x*x+y*y);
			}
			cur.insert(i);
		} else cur.erase(e.second-1);
	}
	printf("%.10f\n", ans+(tot-m)*p);
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50000;
const double PI=acos(-1);
int n;
double a[N], b[N];
long long tot;
std::vector<std::pair<double, int>> event;
void proccess(double d) {
	event.clear();
	for(int i=0; i<n; ++i) {
		double ration=b[i]/sqrt(a[i]*a[i]+1)/d;
		if(fabs(ration)>1) continue;
		double ave=atan2(1, -a[i]), delta=acos(ration);
		if(ave<0) ave+=PI;
		double alp=ave-delta, bet=ave+delta;
		if(alp<=-PI) alp+=2*PI;
		if(bet>PI) bet-=2*PI;
		if(alp>bet) std::swap(alp, bet);
		event.emplace_back(alp, -i-1);
		event.emplace_back(bet, i+1);
	}
	std::sort(event.begin(), event.end());
	tot=0;
	for(int i=0, cnt=0; i<event.size(); ++i) if(event[i].second<0) tot+=cnt++; else --cnt;
}
int main() {
	int m;
	double p, q, ans=0;
	std::set<int> cur;
	assert(scanf("%d%lf%lf%d", &n, &p, &q, &m)==4);
	for(int i=0; i<n; ++i) {
		assert(scanf("%lf%lf", a+i, b+i)==2);
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=3e6; q-p>1e-9; ) {
		double d=(p+q)/2;
		proccess(d);
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	proccess(p);
	for(auto e: event) {
		if(e.second<0) {
			int i=-e.second-1;
			for(int j: cur) {
				double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
				ans+=sqrt(x*x+y*y);
			}
			cur.insert(i);
		} else cur.erase(e.second-1);
	}
	printf("%.10f\n", ans+(tot-m)*p);
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50000;
const long double PI=acosl(-1);
int n, size, l[N], r[N], bit[2*N], prev[2*N], next[2*N];
long double a[N], b[N];
std::pair<long double, int> event[2*N];
void extract(long double d) {
	size=0;
	for(int i=0; i<n; ++i) {
		long double A=a[i]*a[i]+1, B=-a[i]*b[i], Delta=B*B-A*(b[i]*b[i]-d*d);
		if(Delta<0) continue;
		long double x1=(-a[i]*b[i]-sqrtl(Delta))/A, x2=(-a[i]*b[i]+sqrtl(Delta))/A;
		event[size++]={atan2l(a[i]*x1+b[i], x1), i};
		event[size++]={atan2l(a[i]*x2+b[i], x2), i};
	}
	std::sort(event, event+size);
	memset(l, -1, n*sizeof(int));
	memset(r, -1, n*sizeof(int));
	for(int i=0; i<size; ++i) {
		int id=event[i].second;
		id[l[id]==-1?l:r]=i;
	}
}
long long query(int x) {
	long long s=0;
	for(; x; x&=x-1) s+=bit[x];
	return s;
}
void increase(int x) {
	for(; x<size; x+=x&-x) ++bit[x];
}
int main() {
	int m;
	long double p, q, ans=0;
	std::set<int> cur;
	std::cin>>n>>p>>q>>m;
	for(int i=0; i<n; ++i) {
		std::cin>>a[i]>>b[i];
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=1e10; q-p>1e-6; ) {
		int cnt=0;
		long double d=(p+q)/2;
		long long tot=0;
		extract(d);
		memset(bit, 0, size*sizeof(int));
		for(int id=0; id<size; ++id) {
			int i=event[id].second;
			if(r[i]==id) continue;
			tot+=query(r[i])-query(l[i]);
			increase(r[i]);
		}
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	for(int i=1; i<size; ++i) prev[i]=i-1, next[i-1]=i;
	prev[0]=size-1, next[size-1]=0;
	for(int id=size; id--; ) {
		int i=event[id].second, L=l[i], R=r[i];
		if(id==R) continue;
		for(int it=L; (it=next[it])!=R; ) {
			int j=event[it].second;
			long double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
			ans+=sqrtl(x*x+y*y);
			--m;
		}
		prev[next[L]]=prev[L], next[prev[L]]=next[L];
		prev[next[R]]=prev[R], next[prev[R]]=next[R];
	}
	std::cout<<std::fixed<<std::setprecision(9)<<(ans+m*p)<<std::endl;
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50001;
const double PI=acos(-1);
int n;
double a[N], b[N];
std::vector<std::pair<double, int>> event;
void proccess(double d) {
	event.clear();
	for(int i=1; i<=n; ++i) {
		double ration=b[i]/sqrt(a[i]*a[i]+1)/d;
		if(fabs(ration)>1) continue;
		double ave=atan2(1, -a[i]), delta=acos(ration);
		if(ave<0) ave+=PI;
		double alp=ave-delta, bet=ave+delta;
		if(alp<=-PI) alp+=2*PI;
		if(bet>PI) bet-=2*PI;
		if(alp>bet) std::swap(alp, bet);
		event.emplace_back(alp, -i);
		event.emplace_back(bet, i);
	}
	std::sort(event.begin(), event.end());
}
int main() {
	int m;
	double p, q, ans=0;
	std::set<int> cur;
	assert(scanf("%d%lf%lf%d", &n, &p, &q, &m)==4);
	for(int i=1; i<=n; ++i) {
		assert(scanf("%lf%lf", a+i, b+i)==2);
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=3e6; q-p>1e-9; ) {
		int cnt=0;
		double d=(p+q)/2;
		long long tot=0;
		proccess(d);
		for(auto e: event) if(e.second<0) tot+=cnt++; else --cnt;
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	proccess(p);
	for(auto e: event) {
		if(e.second<0) {
			int i=-e.second;
			for(int j: cur) {
				double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
				ans+=sqrt(x*x+y*y);
				--m;
			}
			cur.insert(i);
		} else cur.erase(e.second);
	}
	printf("%.10f\n", ans+m*p);
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50000;
const long double PI=acosl(-1);
int n, size, l[N], r[N], prev[2*N], next[2*N];
long long bit[2*N];
long double a[N], b[N];
std::vector<std::pair<long double, int>> event;
void extract(long double d) {
	event.clear();
	for(int i=0; i<n; ++i) {
		long double A=a[i]*a[i]+1, B=-a[i]*b[i], Delta=B*B-A*(b[i]*b[i]-d*d);
		if(Delta<0) continue;
		long double x1=(-a[i]*b[i]-sqrtl(Delta))/A, x2=(-a[i]*b[i]+sqrtl(Delta))/A;
		event.emplace_back(atan2l(a[i]*x1+b[i], x1), i);
		event.emplace_back(atan2l(a[i]*x2+b[i], x2), i);
	}
	std::sort(event.begin(), event.end());
	size=event.size();
	memset(l, -1, n*sizeof(int));
	memset(r, -1, n*sizeof(int));
	for(int i=0; i<size; ++i) {
		int id=event[i].second;
		id[l[id]==-1?l:r]=i;
	}
}
long long query(int x) {
	long long s=0;
	for(; x; x&=x-1) s+=bit[x];
	return s;
}
void increase(int x, int v=1) {
	for(; x<size; x+=x&-x) bit[x]+=v;
}
int main() {
	int m;
	long double p, q, ans=0;
	std::set<int> cur;
	std::cin>>n>>p>>q>>m;
	for(int i=0; i<n; ++i) {
		std::cin>>a[i]>>b[i];
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=1e18; q-p>1e-9; ) {
		int cnt=0;
		long double d=(p+q)/2;
		long long tot=0;
		extract(d);
		memset(bit, 0, size*sizeof(long long));
		for(int id=0; id<size; ++id) {
			int i=event[id].second;
			if(r[i]==id) continue;
			tot+=query(r[i])-query(l[i]);
			increase(r[i], 1);
		}
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	for(int i=1; i<size; ++i) prev[i]=i-1, next[i-1]=i;
	prev[0]=size-1, next[size-1]=0;
	for(int id=size; id--; ) {
		int i=event[id].second, L=l[i], R=r[i];
		if(id==R) continue;
		for(int it=L; (it=next[it])!=R; ) {
			int j=event[it].second;
			long double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
			ans+=sqrtl(x*x+y*y);
			--m;
		}
		prev[next[L]]=prev[L], next[prev[L]]=next[L];
		prev[next[R]]=prev[R], next[prev[R]]=next[R];
	}
	std::cout<<std::fixed<<std::setprecision(9)<<(ans+m*p)<<std::endl;
	return 0;
}


#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
const int N=50000;
const long double PI=acosl(-1);
int n, size, l[N], r[N], bit[2*N], prev[2*N], next[2*N];
long double a[N], b[N];
std::pair<long double, int> event[2*N];
void extract(long double d) {
	size=0;
	for(int i=0; i<n; ++i) {
		long double A=a[i]*a[i]+1, B=-a[i]*b[i], Delta=B*B-A*(b[i]*b[i]-d*d);
		if(Delta<0) continue;
		long double x1=(-a[i]*b[i]-sqrtl(Delta))/A, x2=(-a[i]*b[i]+sqrtl(Delta))/A;
		event[size++]={atan2l(a[i]*x1+b[i], x1), i};
		event[size++]={atan2l(a[i]*x2+b[i], x2), i};
	}
	std::sort(event, event+size);
	memset(l, -1, n*sizeof(int));
	memset(r, -1, n*sizeof(int));
	for(int i=0; i<size; ++i) {
		int id=event[i].second;
		id[l[id]==-1?l:r]=i;
	}
}
long long query(int x) {
	long long s=0;
	for(; x; x&=x-1) s+=bit[x];
	return s;
}
void increase(int x) {
	for(; x<size; x+=x&-x) ++bit[x];
}
int main() {
	int m;
	long double p, q, ans=0;
	std::set<int> cur;
	std::cin>>n>>p>>q>>m;
	for(int i=0; i<n; ++i) {
		std::cin>>a[i]>>b[i];
		a[i]/=1000;
		b[i]=(b[i]+p*a[i]-q)/1000;
	}
	for(p=0, q=1e10; q-p>1e-6; ) {
		int cnt=0;
		long double d=(p+q)/2;
		long long tot=0;
		extract(d);
		memset(bit, 0, size*sizeof(int));
		for(int id=0; id<size; ++id) {
			int i=event[id].second;
			if(r[i]==id) continue;
			tot+=query(r[i])-query(l[i]);
			increase(r[i]);
		}
		(tot<=m?p:q)=d;
		if(tot==m) break;
	}
	for(int i=1; i<size; ++i) prev[i]=i-1, next[i-1]=i;
	prev[0]=size-1, next[size-1]=0;
	for(int id=size; id--; ) {
		int i=event[id].second, L=l[i], R=r[i];
		if(id==R) continue;
		for(int it=L; (it=next[it])!=R; ) {
			int j=event[it].second;
			long double x=(b[i]-b[j])/(a[j]-a[i]), y=a[i]*x+b[i];
			ans+=sqrtl(x*x+y*y);
			assert(--m>=0);
		}
		prev[next[L]]=prev[L], next[prev[L]]=next[L];
		prev[next[R]]=prev[R], next[prev[R]]=next[R];
	}
	std::cout<<std::fixed<<std::setprecision(9)<<(ans+m*p)<<std::endl;
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const double EPS=1e-9;
const double Pi=acos(-1.0);
struct Point
{
	double x,y;
	int id;
	Point(double xx=0,double yy=0){x=xx,y=yy;}
	inline Point operator+(Point p){return Point(x+p.x,y+p.y);}
	inline Point operator-(Point p){return Point(x-p.x,y-p.y);}
	inline Point operator*(double d){return Point(x*d,y*d);}
	inline Point operator/(double d){return Point(x/d,y/d);}
	inline double dot(Point p){return x*p.x+y*p.y;}
	inline double det(Point p){return x*p.y-y*p.x;}
	inline double abs2(){return x*x+y*y;}
	inline double abs(){return sqrt(abs2());}
	inline Point unit(){return *this/abs();}
	inline Point rot90(){return Point(-y,x);}
	inline int quad()
	{
		if(x<0&&y<=0)return 1;
		if(x>=0&&y<0)return 2;
		if(x>0&&y>=0)return 3;
		return 4;
	}
}a[50005],b[50005],p[100005];
struct Node
{
	int l,r;
}line[50005];
int n,m,tot,num,c[100005],last[100005],pre[100005],nxt[100005];
inline double dis2(Point p1,Point p2)
{
	return p1.det(p2)*p1.det(p2)/(p2-p1).abs2();
}
inline pair<Point,Point>isCL(Point p1,Point p2,double r)
{
	double d=dis2(p1,p2);
	Point m=(p2-p1).unit().rot90()*sqrt(d);
	if(p1.det(p2)>0)m=m*(-1.0);
	d=sqrt(max(0.0,r*r-d));
	Point dir=(p2-p1).unit()*d;
	return make_pair(m+dir,m-dir);
}
inline Point isLL(Point p1,Point p2,Point q1,Point q2)
{
	double a=(q1-p1).det(p2-p1);
	double b=(p2-p1).det(q2-p1);
	return q1+(q2-q1)*a/(a+b);
}
void add(int p)
{
	while(p<=tot)
	{
		c[p]++;
		p+=p^(p&(p-1));
	}
}
int ask(int p)
{
	int ans=0;
	while(p)
	{
		ans+=c[p];
		p&=p-1;
	}
	return ans;
}
int ask(int l,int r)
{
	return ask(r)-ask(l-1);
}
inline bool cmp(Point a,Point b)
{
	return a.quad()==b.quad()?a.det(b)>=0:a.quad()<b.quad();
}
inline bool cmp2(Node a,Node b)
{
	return a.r-a.l<b.r-b.l;
}
void Pre(double r)
{
//	printf("%lf:\n",r);
	tot=0;
	for(int i=1;i<=n;i++)
	{
		if(dis2(a[i],b[i])>r*r+EPS)continue;
		pair<Point,Point>res=isCL(a[i],b[i],r);
		p[++tot]=res.first;
		p[++tot]=res.second;
		p[tot-1].id=p[tot].id=i;
//		printf("(%lf,%lf) (%lf,%lf)\n",p[tot-1].x,p[tot-1].y,p[tot].x,p[tot].y);
	}
	sort(p+1,p+tot+1,cmp);
	for(int i=1;i<=tot;i++)last[p[i].id]=i;
}
bool check(double r)
{
	memset(c,0,sizeof(c));
	Pre(r);
	long long sum=0;
	for(int i=1;i<=tot;i++)
	{
		if(last[p[i].id]==i)continue;
		sum+=ask(i+1,last[p[i].id]-1);
		add(last[p[i].id]);
	}
	return sum>m;
}
int main()
{
	scanf("%d",&n);
	double x,y;
	scanf("%lf%lf%d",&x,&y,&m);
	x/=1000,y/=1000;
	for(int i=1;i<=n;i++)
	{
		double aa,bb;
		scanf("%lf%lf",&aa,&bb);
		aa/=1000,bb/=1000;
		a[i]=Point(0,bb),b[i]=Point(1,aa+bb);
		a[i]=a[i]-Point(x,y);
		b[i]=b[i]-Point(x,y);
//		printf("(%lf,%lf)->(%lf,%lf)\n",a[i].x,a[i].y,b[i].x,b[i].y);
	}
	double l=1e-18,r=1e18;
	for(int i=1;i<=30;i++)
	{
		double mid=sqrt(l*r);
		if(check(mid))r=mid;
		else l=mid;
	}
	r=l;
	Pre(r);
	for(int i=1;i<=tot;i++)
	{
		if(last[p[i].id]==i)continue;
		line[++num].l=i,line[num].r=last[p[i].id];
	}
	sort(line+1,line+num+1,cmp2);
	int sum=0;
	double ans=0;
	for(int i=1;i<=tot;i++)pre[i]=i-1,nxt[i]=i+1;
	for(int i=1;i<=num;i++)
	{
		int x=line[i].l,pos=p[line[i].l].id;
		x=nxt[x];
		while(x!=line[i].r)
		{
			ans+=isLL(a[pos],b[pos],a[p[x].id],b[p[x].id]).abs();
			sum++;
			x=nxt[x];
		}
		x=line[i].l;
		pre[nxt[x]]=pre[x];
		nxt[pre[x]]=nxt[x];
		x=line[i].r;
		pre[nxt[x]]=pre[x];
		nxt[pre[x]]=nxt[x];
	}
	ans+=r*(m-sum);
	printf("%.12lf\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
#define EREP(i,u) for(int i=start[u];i;i=e[i].next)
#define fi first
#define se second
#define mkr(a,b) make_pair(a,b)
#define SZ(A) ((int)A.size())
template<class T>inline void chkmin(T &a,T b){ if(a>b)a=b;}
template<class T>inline void chkmax(T &a,T b){ if(a<b)a=b;}
inline int read()
{
	int s=0,f=1;char ch=getchar();
	while(!isdigit(ch) && ch!='-')ch=getchar();
	if(ch=='-')ch=getchar(),f=-1;
	while(isdigit(ch))s=s*10+ch-'0',ch=getchar();
	return ~f?s:-s;
}

const int maxn=1e5+20;

const double eps=1e-12;
const double Pi=acos(-1);

struct point {
	double x,y;
	point(double _x=0,double _y=0){ x=_x; y=_y;}
	inline double len(){ return sqrt(x*x+y*y);}
};
point S;ll m;

inline point operator -(point a,point b){ return point(a.x-b.x,a.y-b.y);}

struct line {
	double k,b;
	line(double _k=0,double _b=0){ k=_k; b=_b;}
};
line a[maxn];
double angle[maxn];

inline point Intersection(line a,line b)
{
	double x=(a.b-b.b)/(b.k-a.k),y=a.k*x+a.b;
	return point(x,y);
}

line p[maxn];

int n;

inline void init()
{
	n=read();
	S.x=read(); S.y=read(); m=read();
	S.x/=1000; S.y/=1000;
	REP(i,1,n)
	{
		double k=read(),b=read();
		k/=1000; b/=1000;
		a[i]=line(k,b);
		angle[i]=atan(a[i].k);
		if(k*S.x+b>S.y)angle[i]+=Pi*0.5;
		else angle[i]-=Pi*0.5;
	}
}

inline double Dis(line a,point S)
{
	return fabs(a.k*S.x-S.y+a.b)/sqrt(a.k*a.k+1);
}

struct pdd {
	double fi,se;
	int id;
};

inline bool operator < (pdd a,pdd b){ return a.fi<b.fi;}

//#define pdd pair<double,double>

pdd b[maxn];
double sx[maxn];
int num,tx;
int s[maxn];

inline void Add(int x){ for(;x<=tx;x+=x&(-x))s[x]++;}
inline int Sum(int x){ int res=0;for(;x;x-=x&(-x))res+=s[x];return res; }

inline void Check(double &x)
{
	while(x<-Pi)x+=2*Pi;
	while(x>Pi)x-=2*Pi;
}

inline ll check(double R)
{
	num=0; tx=0;
	REP(i,1,n)
	{
		double t=Dis(a[i],S);
		if(t>=R)continue;
		double jd=acos(t/R);
		++num;
		b[num].fi=angle[i]-jd; b[num].se=angle[i]+jd; b[num].id=i;
		Check(b[num].fi); Check(b[num].se);
		if(b[num].fi>b[num].se)swap(b[num].fi,b[num].se);
		sx[++tx]=b[num].fi; sx[++tx]=b[num].se;
	}
	sort(sx+1,sx+tx+1); tx=unique(sx+1,sx+tx+1)-sx-1;
	REP(i,1,num)b[i].fi=lower_bound(sx+1,sx+tx+1,b[i].fi)-sx,b[i].se=lower_bound(sx+1,sx+tx+1,b[i].se)-sx;
	sort(b+1,b+num+1);
	memset(s,0,sizeof(int)*(tx+1));
	ll ans=0;
	REP(i,1,num)
	{
		ans+=Sum(b[i].se)-Sum(b[i].fi);
		Add(b[i].se);
	}
	return ans;
}

struct node {
	int pos;int id;
};
inline bool operator < (node a,node b){ return a.pos==b.pos?a.id<b.id:a.pos<b.pos;}

double ans;int NUM;

inline double Calc(int i,int j)
{
	point t=Intersection(a[i],a[j]);
	return (t-S).len();
}

inline void Find(double R)
{
	num=0; tx=0;
	REP(i,1,n)
	{
		double t=Dis(a[i],S);
		if(t>=R)continue;
		double jd=acos(t/R);
		++num;
		b[num].fi=angle[i]-jd; b[num].se=angle[i]+jd; b[num].id=i;
		Check(b[num].fi); Check(b[num].se);
		if(b[num].fi>b[num].se)swap(b[num].fi,b[num].se);
		sx[++tx]=b[num].fi; sx[++tx]=b[num].se;
	}
	sort(sx+1,sx+tx+1); tx=unique(sx+1,sx+tx+1)-sx-1;
	REP(i,1,num)b[i].fi=lower_bound(sx+1,sx+tx+1,b[i].fi)-sx,b[i].se=lower_bound(sx+1,sx+tx+1,b[i].se)-sx;
	sort(b+1,b+num+1);

	set<node>s;
	REP(i,1,num)
	{
		set<node>::iterator it;
		it=s.lower_bound((node){b[i].fi,0});
		for(;it!=s.end() && it->pos<b[i].se;it++)
		{
			ans+=Calc(b[i].id,it->id);
			NUM++;
		}
		s.insert((node){b[i].se,b[i].id});
//Add(b[i].se);
	}
}

inline void doing()
{
	double l=0,r=1e10;
	REP(th,1,100)
	{
		double mid=(l+r)*0.5;
		if(check(mid)>=m)r=mid;
		else l=mid;
	}
	Find(l);
	printf("%.10lf\n",ans+l*(m-NUM));
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("CF607E.in","r",stdin);
	freopen("CF607E.out","w",stdout);
#endif
	init();
	doing();
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set>

typedef double r64;
typedef long long LL;
const r64 eps = 1e-6;
const int MN = 50005;

int N, M;
r64 k[MN], b[MN], Ans;

LL check(r64 rad, int typ) {
	static r64 t[MN * 2];
	static int p[MN * 2], ip[MN * 2], bit[MN * 2];
	static std::set<int> st;
	int cnt = 0;
	for (int i = 1; i <= N; ++i) {
		r64 d = (k[i] * k[i] + 1) * rad * rad - b[i] * b[i], x, y;
		if (d < 0) continue;
		d = sqrt(d);
		x = (-k[i] * b[i] + d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		x = (-k[i] * b[i] - d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		if (t[cnt - 1] > t[cnt]) std::swap(t[cnt - 1], t[cnt]);
	}
	std::sort(p + 1, p + cnt + 1, [](int i, int j) { return t[i] < t[j]; });
	for (int i = 1; i <= cnt; ++i) ip[p[i]] = i;
	if (typ) {
		int sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) st.insert(id);
			else {
				st.erase(ip[i - 1]);
				for (auto it = st.lower_bound(ip[i - 1]); it != st.end(); ++it) {
					int u = p[*it] / 2 + 1, v = i / 2;
					r64 x = (b[u] - b[v]) / (k[v] - k[u]);
					r64 y = k[u] * x + b[u];
					Ans += sqrt(x * x + y * y);
					++sum;
				}
			}
		}
		return sum;
	} else {
		for (int i = 1; i <= cnt; ++i) bit[i] = 0;
		auto Add = [&](int i, int x) { for (; i <= cnt; i += i & -i) bit[i] += x; };
		auto Qur = [&](int i) { int a = 0; for (; i; i -= i & -i) a += bit[i]; return a; };
		int num = 0; LL sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) Add(id, 1), ++num;
			else sum += num - Qur(ip[i - 1]), Add(ip[i - 1], -1), --num;
		}
		return sum;
	}
}

int main() {
	r64 ox, oy;
	scanf("%d%lf%lf%d", &N, &ox, &oy, &M);
	ox /= 1000, oy /= 1000;
	for (int i = 1; i <= N; ++i) {
		scanf("%lf%lf", &k[i], &b[i]);
		k[i] /= 1000, b[i] /= 1000;
		b[i] += ox * k[i] - oy;
	}
	r64 lb = 0, rb = 2.1e9, mid, ans = 0;
	while (lb <= rb - eps) {
		mid = (lb + rb) / 2;
		if (check(mid, 0) < M) ans = lb = mid;
		else rb = mid;
	}
	int num = check(ans, 1);
	if (N == 2000) printf("%.10f, %.10lf, %d\n", ans, Ans, num);
	printf("%.10f\n", Ans + (M - num) * ans);
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set>

typedef double r64;
typedef long long LL;
const r64 eps = 1e-6;
const int MN = 50005;

int N, M;
r64 k[MN], b[MN], Ans;

LL check(r64 rad, int typ) {
	static r64 t[MN * 2];
	static int p[MN * 2], ip[MN * 2], lid[MN], bit[MN * 2];
	static std::set<int> st;
	int cnt = 0;
	for (int i = 1; i <= N; ++i) {
		r64 d = (k[i] * k[i] + 1) * rad * rad - b[i] * b[i], x, y;
		if (d < 0) continue;
		d = sqrt(d);
		x = (-k[i] * b[i] + d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		x = (-k[i] * b[i] - d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		if (t[cnt - 1] > t[cnt]) std::swap(t[cnt - 1], t[cnt]);
		lid[cnt / 2] = i;
	}
	std::sort(p + 1, p + cnt + 1, [](int i, int j) { return t[i] < t[j]; });
	for (int i = 1; i <= cnt; ++i) ip[p[i]] = i;
	if (typ) {
		int sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) st.insert(id);
			else {
				st.erase(ip[i - 1]);
				for (auto it = st.lower_bound(ip[i - 1]); it != st.end(); ++it) {
					int u = lid[p[*it] / 2 + 1], v = lid[i / 2];
					r64 x = (b[u] - b[v]) / (k[v] - k[u]);
					r64 y = k[u] * x + b[u];
					Ans += sqrt(x * x + y * y);
					++sum;
				}
			}
		}
		return sum;
	} else {
		for (int i = 1; i <= cnt; ++i) bit[i] = 0;
		auto Add = [&](int i, int x) { for (; i <= cnt; i += i & -i) bit[i] += x; };
		auto Qur = [&](int i) { int a = 0; for (; i; i -= i & -i) a += bit[i]; return a; };
		int num = 0; LL sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) Add(id, 1), ++num;
			else sum += num - Qur(ip[i - 1]), Add(ip[i - 1], -1), --num;
		}
		return sum;
	}
}

int main() {
	r64 ox, oy;
	scanf("%d%lf%lf%d", &N, &ox, &oy, &M);
	ox /= 1000, oy /= 1000;
	for (int i = 1; i <= N; ++i) {
		scanf("%lf%lf", &k[i], &b[i]);
		k[i] /= 1000, b[i] /= 1000;
		b[i] += ox * k[i] - oy;
	}
	r64 lb = 0, rb = 2.1e9, mid, ans = 0;
	while (lb <= rb - eps) {
		mid = (lb + rb) / 2;
		if (check(mid, 0) < M) ans = lb = mid;
		else rb = mid;
	}
	int num = check(ans, 1);
	printf("%.10f\n", Ans + (M - num) * ans);
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set>

typedef double r64;
typedef long long LL;
const r64 eps = 1e-6;
const int MN = 50005;

int N, M;
r64 k[MN], b[MN], Ans;

LL check(r64 rad, int typ) {
	static r64 t[MN * 2];
	static int p[MN * 2], ip[MN * 2], bit[MN * 2];
	static std::set<int> st;
	int cnt = 0;
	for (int i = 1; i <= N; ++i) {
		r64 d = (k[i] * k[i] + 1) * rad * rad - b[i] * b[i], x, y;
		if (d < 0) continue;
		d = sqrt(d);
		x = (-k[i] * b[i] + d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		x = (-k[i] * b[i] - d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		if (t[cnt - 1] > t[cnt]) std::swap(t[cnt - 1], t[cnt]);
	}
	std::sort(p + 1, p + cnt + 1, [](int i, int j) { return t[i] < t[j]; });
	for (int i = 1; i <= cnt; ++i) ip[p[i]] = i;
	if (typ) {
		int sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) st.insert(id);
			else {
				st.erase(ip[i - 1]);
				for (auto it = st.lower_bound(ip[i - 1]); it != st.end(); ++it) {
					int u = p[*it] / 2 + 1, v = i / 2;
					r64 x = (b[u] - b[v]) / (k[v] - k[u]);
					r64 y = k[u] * x + b[u];
					Ans += sqrt(x * x + y * y);
					++sum;
				}
			}
		}
		return sum;
	} else {
		for (int i = 1; i <= cnt; ++i) bit[i] = 0;
		auto Add = [&](int i, int x) { for (; i <= cnt; i += i & -i) bit[i] += x; };
		auto Qur = [&](int i) { int a = 0; for (; i; i -= i & -i) a += bit[i]; return a; };
		int num = 0; LL sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) Add(id, 1), ++num;
			else sum += num - Qur(ip[i - 1]), Add(ip[i - 1], -1), --num;
		}
		return sum;
	}
}

int main() {
	r64 ox, oy;
	scanf("%d%lf%lf%d", &N, &ox, &oy, &M);
	ox /= 1000, oy /= 1000;
	for (int i = 1; i <= N; ++i) {
		scanf("%lf%lf", &k[i], &b[i]);
		k[i] /= 1000, b[i] /= 1000;
		b[i] += ox * k[i] - oy;
	}
	r64 lb = 0, rb = 4e9, mid, ans = 0;
	while (lb <= rb - eps) {
		mid = (lb + rb) / 2;
		if (check(mid, 0) < M) ans = lb = mid;
		else rb = mid;
	}
	int num = check(ans, 1);
	printf("%.10f\n", Ans + (M - num) * ans);
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set>

typedef double r64;
typedef long long LL;
const r64 eps = 1e-6;
const int MN = 50005;

int N, M;
r64 k[MN], b[MN], Ans;

LL check(r64 rad, int typ) {
	static r64 t[MN * 2];
	static int p[MN * 2], ip[MN * 2], bit[MN * 2];
	static std::set<int> st;
	int cnt = 0;
	for (int i = 1; i <= N; ++i) {
		r64 d = (k[i] * k[i] + 1) * rad * rad - b[i] * b[i], x, y;
		if (d < 0) continue;
		d = sqrt(d);
		x = (-k[i] * b[i] + d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		x = (-k[i] * b[i] - d) / (k[i] * k[i] + 1), y = k[i] * x + b[i];
		t[++cnt] = atan2(y, x), p[cnt] = cnt;
		if (t[cnt - 1] > t[cnt]) std::swap(t[cnt - 1], t[cnt]);
	}
	std::sort(p + 1, p + cnt + 1, [](int i, int j) { return t[i] < t[j]; });
	for (int i = 1; i <= cnt; ++i) ip[p[i]] = i;
	if (typ) {
		int sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) st.insert(id);
			else {
				st.erase(ip[i - 1]);
				for (auto it = st.lower_bound(ip[i - 1]); it != st.end(); ++it) {
					int u = p[*it] / 2 + 1, v = i / 2;
					r64 x = (b[u] - b[v]) / (k[v] - k[u]);
					r64 y = k[u] * x + b[u];
					Ans += sqrt(x * x + y * y);
					++sum;
				}
			}
		}
		return sum;
	} else {
		for (int i = 1; i <= cnt; ++i) bit[i] = 0;
		auto Add = [&](int i, int x) { for (; i <= cnt; i += i & -i) bit[i] += x; };
		auto Qur = [&](int i) { int a = 0; for (; i; i -= i & -i) a += bit[i]; return a; };
		int num = 0; LL sum = 0;
		for (int id = 1; id <= cnt; ++id) {
			int i = p[id];
			if (i & 1) Add(id, 1), ++num;
			else sum += num - Qur(ip[i - 1]), Add(ip[i - 1], -1), --num;
		}
		return sum;
	}
}

int main() {
	r64 ox, oy;
	scanf("%d%lf%lf%d", &N, &ox, &oy, &M);
	ox /= 1000, oy /= 1000;
	for (int i = 1; i <= N; ++i) {
		scanf("%lf%lf", &k[i], &b[i]);
		k[i] /= 1000, b[i] /= 1000;
		b[i] += ox * k[i] - oy;
	}
	r64 lb = 0, rb = 2.1e9, mid, ans = 0;
	while (lb <= rb - eps) {
		mid = (lb + rb) / 2;
		if (check(mid, 0) < M) ans = lb = mid;
		else rb = mid;
	}
	int num = check(ans, 1);
	if (N == 2000) printf("%.10f\n", ans);
	printf("%.10f\n", Ans + (M - num) * ans);
	return 0;
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	assert(cnt<=m);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		//
		if(lim>=200010)printf("fenwick tree over flow %d\n",lim);
		assert(lim<200010);
		//
	}
	void add(int x, int y){
		//
		if(x<=0)printf("add %d\n",x);
		assert(x>0);
		//
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		//
		if(x<0)printf("qs %d\n",x);
		assert(x>0);
		//
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						//
						if(dcmp(dis,R)!=-1)printf("%lf %lf\n",dis,R);
						assert(dcmp(dis,R)==-1);
						//
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y]-1, rr = lim+id[k]+1;
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	//
	if(cnt>m)printf("cnt bao le %d %d\n",cnt,m);
	assert(cnt<=m);
	//
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}


/*
 * Author : Remilia Scarlet
 */

// #pragma comment(linker, "/STACK:102400000,102400000")

#include <bits/stdc++.h>

#define For(i,l,r) for(int _r=r,i=l;i<=_r;++i)
#define rep(i,l,r) for(int _r=r,i=l;i<_r;++i)
#define dto(i,r,l) for(int _l=l,i=r;i>=_l;--i)
#define x first
#define y second
#define pb push_back
#define mk make_pair
#define oo (c=getchar())
#define SZ(V) (int(V.size()))
#define ALL(V) V.begin(),V.end()

using namespace std;

typedef double db;
typedef long long LL;
typedef pair<int ,int> PII;
typedef vector<int> VI;
typedef complex<db> cpx;
typedef vector<PII> VII;
// typedef __int128 bigint;

int ran(){return (rand()<<15)+rand();}

int IN(){
	int x=0;char c;
	for(;oo<48 && c^'-' || c>57;);bool f=c=='-';if(f)oo;
	for(;c>47 && c<58;oo)x=(x<<1)+(x<<3)+c-48;return f?-x:x;
}
void print(int x,char en='\n'){
	printf("%d",x);if(en)putchar(en);
}

void hello(){
	freopen("remi.in","r",stdin);
//	freopen("remi.out","w",stdout);
//	srand(time(0));
}

const db eps = 1e-12;

int dcmp(db x, db y){
	return fabs(x-y)<eps?0:x<y?-1:1;
}

struct ww{
	db x,y;
	db polar(){
		return atan2(y,x);
	}
};

struct fenwick_tree{
	int lim,t[200010];
	void pret(int n){
		For(i,1,lim)t[i] = 0;
		lim = n;
		assert(lim<200010);
	}
	void add(int x, int y){
		assert(x>0);
		for(;x<=lim;x+=x&-x)t[x]+=y;
	}
	int qs(int x){
		if(!x)return 0;
		assert(x>0);
		int an = 0;
		for(;x;x-=x&-x)an+=t[x];
		return an;
	}
}ds;

int n,m;
db k[50010],b[50010],fi[50010];

LL count(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	ds.pret(c);
	LL res = 0;
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				res += ds.qs(id[k]-1)-ds.qs(fi[li[k].y]);
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				ds.add(id[k],1);
				ds.add(fi[li[k].y],-1);
			}
		}i=j;
	}
	for(auto it:li)fi[it.y] = 0;
	return res;
}

VI seg_list[524289];

db solve(int i,int j){
	if(dcmp(k[i],k[j]) == 0)return 0;
	db x = (b[j]-b[i])/(k[i]-k[j]);
	db y = k[i]*x+b[i];
	return sqrt(x*x+y*y);
}

db sumup(db R){
	vector<pair<db,int>> li;
	For(i,1,n){
		db k = ::k[i], b = ::b[i];
		db delta = 4*k*k*b*b-4*(1+k*k)*(b*b-R*R);
		if(dcmp(delta,0)<=0)continue;
		db x1 = (-2*k*b+sqrt(delta))/(2*(1+k*k));
		db x2 = (-2*k*b-sqrt(delta))/(2*(1+k*k));
		db y1 = k*x1+b;
		db y2 = k*x2+b;
		ww P = {x1,y1}, Q = {x2,y2};
		li.pb({P.polar(),i});
		li.pb({Q.polar(),i});
	}
	sort(ALL(li));
	VI id(SZ(li));
	int c = 0;
	db la = 0;
	rep(i,0,SZ(li)){
		if(i==0 || dcmp(la,li[i].x)==-1){
			la = li[i].x;
			id[i] = ++c;
		}else{
			id[i] = c;
		}
	}
	db res = 0;
	int lim = 1;
	for(;lim<c+2;lim<<=1);
	for(int i=0;i<SZ(li);){
		int j = i;
		for(;j<SZ(li) && id[j]==id[i];++j);
		rep(k,i,j){
			if(fi[li[k].y]){
				int line1 = li[k].y;
				for(int u = lim+fi[li[k].y];u;u>>=1)
					for(int line2:seg_list[u]){
						db dis = solve(line1,line2);
						res += dis;
					}
			}
		}
		rep(k,i,j){
			if(!fi[li[k].y])fi[li[k].y] = id[k];
			else{
				int ll = lim + fi[li[k].y], rr = lim+id[k];
				for(;ll^rr^1;ll>>=1,rr>>=1){
					if(~ll&1)seg_list[ll^1].pb(li[k].y);
					if(rr&1) seg_list[rr^1].pb(li[k].y);
				}
			}
		}i=j;
	}
	return res;
}

void Main(){
	db ll = 0, rr = 3e9;
	rep(tc,0,100){
		db mm = (ll+rr)*.5;
		if(count(mm)<=m)ll = mm;else rr = mm;
	}
	LL cnt = count(ll);
	assert(cnt<=m);
	// assert(count(ll+eps)>=m);
	db ans = sumup(ll);
	ans += (m-cnt)*ll;
	printf("%.20lf\n",ans);
}

int main(int argc, char* argv[]){
	// hello();
	n = IN();
	ww P;
	P.x = IN()/1000., P.y = IN()/1000.;
	m = IN();
	For(i,1,n)k[i] = IN()/1000., b[i] = IN()/1000.-P.y+k[i]*P.x;
	Main();
}