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

#define FILL(a, n, x) memset((a), (x), sizeof ((a)[0]) * (n))
#define COPY(a, n, b) memcpy((b), (a), sizeof ((a)[0]) * (n))
#define FILLA(a, x) memset((a), (x), sizeof (a))
#define COPYA(a, b) memcpy((b), (a), sizeof (a))

using namespace std;

typedef long long li;
typedef unsigned long long lu;
const li infl = ~0LLU >> 2;

template <class T>
inline void Min(T &x, T y) {
  if (y < x) x = y;
}
template <class T>
inline void Max(T &x, T y) {
  if (y > x) x = y;
}

/*

const int mod = 998244353;
inline int Add(int x) { return x >= mod ? x - mod : x; }
inline void Add(int &x, int y) { x += y; if (x >= mod) x -= mod; }
inline int Sub(int x) { return x < 0 ? x + mod : x; }
inline void Sub(int &x, int y) { x -= y; if (x < 0) x += mod; }
inline int Mul(int x, int y) { return (int)((li)x * y % mod); }
inline int Mul(int x, int y, int z) { return Mul(x, Mul(y, z)); }
int Pow(int x, int y) {
  int z = 1;
  for (; y; y >>= 1) {
    if (y & 1) z = Mul(z, x);
    x = Mul(x, x);
  }
  return z;
}
int Inv(int x) {
  return Pow(x, mod - 2);
}

*/

// ----------------------------------------

typedef long double real;

const int maxn = 50000;
const real scale = 1e3, pi = acos(-1.0L), eps = 1e-12L;

int n, m, ns;
real cx, cy;
real la[maxn], lb[maxn];

pair<real, real> seg[maxn];
real arcs[maxn * 2];

struct Seg {
  int l, r, id;
  bool operator < (const Seg &b) const {
    return l < b.l || (l == b.l && r < b.r);
  }
} segi[maxn];

int ord[maxn];

real Fix(real x) {
  while (x >= pi) x -= 2 * pi;
  while (x < -pi) x += 2 * pi;
  return x;
}

void MakeSegments(real radius) {
  ns = 0;

  for (int i = 0; i < n; ++i) {
    real down = sqrt(la[i] * la[i] + 1);
    real up = cy - la[i] * cx - lb[i];
    real dist = up / down;  // negative if below, positive if above
    if (abs(dist) > radius) continue;

    real alpha = atan2(la[i], 1) - pi / 2;
    if (dist < 0) {
      dist *= -1;
      alpha += pi;
    }

    real len_sqr = radius * radius - dist * dist;
    real delta = acos((radius * radius + dist * dist - len_sqr) /
                      (2 * radius * dist));
    if (dist < eps) delta = pi / 2;
    real beta1 = Fix(alpha + delta), beta2 = Fix(alpha - delta);
    if (beta1 > beta2) swap(beta1, beta2);
    seg[ns] = {beta1, beta2};

    arcs[2 * ns] = beta1;
    arcs[2 * ns + 1] = beta2;

    segi[ns].id = i;
    ++ns;
  }

  sort(arcs, arcs + 2 * ns);

  for (int i = 0; i < ns; ++i) {
    segi[i].l = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].first) - arcs);
    segi[i].r = (int)(lower_bound(arcs, arcs + 2 * ns, seg[i].second) - arcs);
  }
  sort(segi, segi + ns);

  for (int i = 0; i < ns; ++i) {
    ord[i] = i;
  }
  sort(ord, ord + ns, [](int i, int j) { return segi[i].r < segi[j].r; });
}

namespace bit {
  int N;
  int bit[2 * maxn];

  void Init(void) {
    N = 2 * ns;
    FILLA(bit, 0);
  }

  int Low(int i) {
    return i & -i;
  }

  void Add(int i, int x) {
    for (; i < N; i += Low(i + 1)) {
      bit[i] += x;
    }
  }

  int Sum(int i) {
    int sum = 0;
    for (; i >= 0; i -= Low(i + 1)) {
      sum += bit[i];
    }
    return sum;
  }
}

li Count(real radius) {
  MakeSegments(radius);

  bit::Init();
  using bit::Add;
  using bit::Sum;

  li ans = 0;
  int next = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      Add(segi[ord[next]].r, -1);
      ++next;
    }
    ans += Sum(r);
    Add(r, 1);
  }

  return ans;
}

struct Cmp {
  bool operator () (const Seg &a, const Seg &b) const {
    if (a.r != b.r) return a.r < b.r;
    return a.id < b.id;
  }
};

void Get(int id, real &k, real &b) {
  k = la[id];
  b = lb[id];
}

real Cost(int id1, int id2) {
  real k1, b1, k2, b2;
  Get(id1, k1, b1);
  Get(id2, k2, b2);
  real x = (b2 - b1) / (k1 - k2);
  real y = k1 * x + b1;
  x -= cx;
  y -= cy;
  // printf("Cost(%d, %d): %Lf, %Lf\n", id1, id2, x, y);
  return sqrt(x * x + y * y);
}

pair<li, real> Output(real radius) {
  MakeSegments(radius);

  // printf("-------------------- Start Output %Lf --------------------\n", radius);
  // for (int i = 0; i < ns; ++i) {
  //   printf("seg %Lf %Lf\n", seg[i].first / pi, seg[i].second / pi);
  // }
  // for (int i = 0; i < ns; ++i) {
  //   printf("segi %d %d %d\n", segi[i].l, segi[i].r, i);
  // }

  set<Seg, Cmp> s;
  typedef set<Seg, Cmp>::iterator Iter;

  li cnt = 0;
  int next = 0;
  real sum = 0;
  for (int i = 0; i < ns; ++i) {
    int l = segi[i].l, r = segi[i].r;
    while (next < ns && segi[ord[next]].r < l) {
      s.erase(segi[ord[next]]);
      ++next;
    }
    for (Iter x = s.begin(); x != s.end(); ++x) {
      if (x->r > r) break;
      ++cnt;
      sum += Cost(x->id, segi[i].id);
    }
    s.insert(segi[i]);
  }

  // printf("cnt = %d\n", (int)cnt);
  return {cnt, sum};
}

real Solve(void) {
  real low = 0, high = 1e12;
  for (int i = 0; i < 100; ++i) {
    real mid = (low + high) * 0.5;
    if (Count(mid) > m) {
      high = mid;
    } else {
      low = mid;
    }
  }
  // printf("low = %Lf\n", low);
  real radius = low;
  pair<li, real> res = Output(radius);
  return res.second + (real)(m - res.first) * radius;
}

int main(void) {
  scanf("%d", &n);
  int x, y;
  scanf("%d%d%d", &x, &y, &m);
  cx = x / scale;
  cy = y / scale;

  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x, &y);
    la[i] = x / scale;
    lb[i] = y / scale;
  }
  real ans = Solve();
  printf("%.20Lf\n", ans);
  return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cassert>
#include<cstring>
#include<vector>
#include<set>
#include<algorithm>

int n;

long double X0,Y0;
int M;

struct Point{
	long double X,Y;
	Point(){X=Y=0;}
	Point(long double X_,long double Y_){X=X_,Y=Y_;}
};
struct Circle{
	Point O;
	long double R;
	Circle(){R=0;}
	Circle(const Point &O_,long double R_){O=O_,R=R_;}
};
struct Line{ // y=kx+b
	long double K,B;
	Line(){K=B=0;}
	Line(long double K_,long double B_){K=K_,B=B_;}
}L[50050];

inline long double sqr(long double k){return k*k;}
inline long double distance(const Point &A,const Point &B){return sqrtl(sqr(A.X-B.X)+sqr(A.Y-B.Y));}
// inline long double distance(const Point &P,const Line &L){
// 	long double X=(P.Y+P.X/L.K-L.B)/(L.K+1/L.K);
// 	return distance(P,Point(X,X*L.K+L.B));
// }
std::pair<bool,std::pair<long double,long double> > checkIntersection(const Circle &C,const Line &L){
//	long double dis=distance(C.O,L);
//	if (dis>C.R) return std::make_pair(false,std::make_pair(0,0));
	long double P=1+sqr(L.K),Q=-2*C.O.X+2*L.K*(L.B-C.O.Y),R=sqr(C.O.X)+sqr(L.B-C.O.Y)-sqr(C.R);
	long double delta=sqr(Q)-4*P*R;
//	std::cout<<"delta="<<delta<<std::endl;
	if (delta<0) return std::make_pair(false,std::make_pair(0,0));
//	assert(delta>=0);
	delta=sqrtl(delta);
	long double X1=(-Q+delta)/(2*P),X2=(-Q-delta)/(2*P);
	long double Y1=L.K*X1+L.B,Y2=L.K*X2+L.B;
	return std::make_pair(true,std::make_pair(atan2l(Y1-C.O.Y,X1-C.O.X),atan2l(Y2-C.O.Y,X2-C.O.X)));
}
Point Intersection(const Line &A,const Line &B){
	long double X=-(A.B-B.B)/(A.K-B.K);
	return Point(X,A.K*X+A.B);
}

const long double eps=1e-8;

int pos[50050],rpos[100050];

struct Fenwick{
	int F[100050],flim;
	void mark(int v){while (v<=flim) F[v]++,v+=v&-v;}
	void remark(int v){while (v<=flim) F[v]--,v+=v&-v;}
	int query(int v){int ret=0;while (v) ret+=F[v],v&=v-1;return ret;}
	int query(int l,int r){return query(r)-query(l-1);}
	void clear(){memset(F,0,sizeof(F));}
}F;

int countInnerPoints(long double rad){
	std::vector<std::pair<long double,int> > PV;
	Circle nowC=Circle(Point(X0,Y0),rad);
	for (int i=1;i<=n;i++){
		auto res=checkIntersection(nowC,L[i]);
		if (!res.first) continue;
		PV.push_back(std::make_pair(res.second.first,i));
		PV.push_back(std::make_pair(res.second.second,i));
	}
	std::sort(PV.begin(),PV.end());
	int ans=0;
	F.flim=PV.size();
	for (int i=0;i<PV.size();i++){
		if (pos[PV[i].second]){
			ans+=F.query(pos[PV[i].second]+1,i);
			F.remark(pos[PV[i].second]);
//			printf("remark %d\n",pos[PV[i].second]);
			pos[PV[i].second]=0;
		}
		else{
			F.mark(i+1);
//			printf("mark %d\n",i+1);
			pos[PV[i].second]=i+1;
		}
	}
	return ans;
}

long double finalcalc(long double rad){
	std::vector<std::pair<long double,int> > PV;
	Circle nowC=Circle(Point(X0,Y0),rad);
	for (int i=1;i<=n;i++){
		auto res=checkIntersection(nowC,L[i]);
		if (!res.first) continue;
		PV.push_back(std::make_pair(res.second.first,i));
		PV.push_back(std::make_pair(res.second.second,i));
	}
	std::sort(PV.begin(),PV.end());
	std::set<int> F;
	long double result=0;
	for (int i=0;i<PV.size();i++){
		if (pos[PV[i].second]){
			auto it=F.lower_bound(pos[PV[i].second]);
			for (auto t=std::next(it);t!=F.end();++t){
//				printf("%d with %d\n",PV[i].second,*t);
				result+=distance(Intersection(L[rpos[*t]],L[PV[i].second]),Point(X0,Y0));
			}
			F.erase(it);
//			std::cout<<"erase "<<*it<<std::endl;
			pos[PV[i].second]=0;
		}
		else{
			rpos[pos[PV[i].second]=i+1]=PV[i].second;
			F.insert(i+1);
//			std::cout<<"insert "<<i+1<<std::endl;
		}
	}
	return result;
}

int main(){
	scanf("%d",&n);
	scanf("%Lf%Lf%d",&X0,&Y0,&M);
	for (int i=1,x,y;i<=n;i++) scanf("%d%d",&x,&y),L[i]=Line(x/1000.,y/1000.);

	X0/=1000,Y0/=1000;

	long double L=0,R=1e20;
	while (R-L>eps){
		long double mdl=(L+R)/2;
//		std::cout<<"mdl="<<mdl<<std::endl;
		int count=countInnerPoints(mdl);
		if (count>=M) R=mdl;
		else L=mdl;
	}
	int finalcount=countInnerPoints(L-eps);
	printf("%.12Lf\n",finalcalc(L-eps)+(M-finalcount)*L);
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cassert>
#include<cstring>
#include<vector>
#include<set>
#include<algorithm>

int n;

long double X0,Y0;
int M;

struct Point{
	long double X,Y;
	Point(){X=Y=0;}
	Point(long double X_,long double Y_){X=X_,Y=Y_;}
};
struct Circle{
	Point O;
	long double R;
	Circle(){R=0;}
	Circle(const Point &O_,long double R_){O=O_,R=R_;}
};
struct Line{ // y=kx+b
	long double K,B;
	Line(){K=B=0;}
	Line(long double K_,long double B_){K=K_,B=B_;}
}L[50050];

inline long double sqr(long double k){return k*k;}
inline long double distance(const Point &A,const Point &B){return sqrtl(sqr(A.X-B.X)+sqr(A.Y-B.Y));}
// inline long double distance(const Point &P,const Line &L){
// 	long double X=(P.Y+P.X/L.K-L.B)/(L.K+1/L.K);
// 	return distance(P,Point(X,X*L.K+L.B));
// }
std::pair<bool,std::pair<long double,long double> > checkIntersection(const Circle &C,const Line &L){
//	long double dis=distance(C.O,L);
//	if (dis>C.R) return std::make_pair(false,std::make_pair(0,0));
	long double P=1+sqr(L.K),Q=-2*C.O.X+2*L.K*(L.B-C.O.Y),R=sqr(C.O.X)+sqr(L.B-C.O.Y)-sqr(C.R);
	long double delta=sqr(Q)-4*P*R;
//	std::cout<<"delta="<<delta<<std::endl;
	if (delta<0) return std::make_pair(false,std::make_pair(0,0));
//	assert(delta>=0);
	delta=sqrtl(delta);
	long double X1=(-Q+delta)/(2*P),X2=(-Q-delta)/(2*P);
	long double Y1=L.K*X1+L.B,Y2=L.K*X2+L.B;
	return std::make_pair(true,std::make_pair(atan2l(Y1-C.O.Y,X1-C.O.X),atan2l(Y2-C.O.Y,X2-C.O.X)));
}
Point Intersection(const Line &A,const Line &B){
	long double X=-(A.B-B.B)/(A.K-B.K);
	return Point(X,A.K*X+A.B);
}

const long double eps=1e-8;

int pos[50050],rpos[100050];

struct Fenwick{
	int F[100050],flim;
	void mark(int v){while (v<=flim) F[v]++,v+=v&-v;}
	void remark(int v){while (v<=flim) F[v]--,v+=v&-v;}
	int query(int v){int ret=0;while (v) ret+=F[v],v&=v-1;return ret;}
	int query(int l,int r){return query(r)-query(l-1);}
	void clear(){memset(F,0,sizeof(F));}
}F;

int countInnerPoints(long double rad){
	if (rad<0) return 0;
	std::vector<std::pair<long double,int> > PV;
	Circle nowC=Circle(Point(X0,Y0),rad);
	for (int i=1;i<=n;i++){
		auto res=checkIntersection(nowC,L[i]);
		if (!res.first) continue;
		PV.push_back(std::make_pair(res.second.first,i));
		PV.push_back(std::make_pair(res.second.second,i));
	}
	std::sort(PV.begin(),PV.end());
	int ans=0;
	F.flim=PV.size();
	for (int i=0;i<PV.size();i++){
		if (pos[PV[i].second]){
			ans+=F.query(pos[PV[i].second]+1,i);
			F.remark(pos[PV[i].second]);
//			printf("remark %d\n",pos[PV[i].second]);
			pos[PV[i].second]=0;
		}
		else{
			F.mark(i+1);
//			printf("mark %d\n",i+1);
			pos[PV[i].second]=i+1;
		}
	}
	return ans;
}

int pre[100050],lst;

long double finalcalc(long double rad){
	if (rad<0) return 0;
	std::vector<std::pair<long double,int> > PV;
	Circle nowC=Circle(Point(X0,Y0),rad);
	for (int i=1;i<=n;i++){
		auto res=checkIntersection(nowC,L[i]);
		if (!res.first) continue;
		PV.push_back(std::make_pair(res.second.first,i));
		PV.push_back(std::make_pair(res.second.second,i));
	}
	std::sort(PV.begin(),PV.end());
	std::set<int> F;
	long double result=0;
	for (int i=0;i<PV.size();i++){
		if (pos[PV[i].second]){
			int ls=lst;
			for (int t=pre[lst];t!=pos[PV[i].second];ls=t,t=pre[t])
				result+=distance(Intersection(L[rpos[t]],L[PV[i].second]),Point(X0,Y0));
			pre[ls]=pre[pre[ls]];
//			printf("ls=%d\n",ls);
//			std::cout<<"erase "<<*it<<std::endl;
			pos[PV[i].second]=0;
		}
		else{
			rpos[pos[PV[i].second]=i+1]=PV[i].second;
			pre[i+1]=pre[lst],lst=i+2,pre[lst]=i+1;
//			std::cout<<"insert "<<i+1<<std::endl;
		}
	}
	return result;
}

int main(){
	scanf("%d",&n);
	scanf("%Lf%Lf%d",&X0,&Y0,&M);
	for (int i=1,x,y;i<=n;i++) scanf("%d%d",&x,&y),L[i]=Line(x/1000.,y/1000.);

	X0/=1000,Y0/=1000;

	long double L=0,R=1e10;
	while (R-L>eps){
		long double mdl=(L+R)/2;
//		std::cout<<"mdl="<<mdl<<std::endl;
		int count=countInnerPoints(mdl);
		if (count>=M) R=mdl;
		else L=mdl;
	}
//	printf("L=%Lf\n",L);
	int finalcount=countInnerPoints(L-eps);
//	printf("finalcount=%d\n",finalcount);
	printf("%.12Lf\n",finalcalc(L-eps)+(M-finalcount)*L);
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cassert>
#include<cstring>
#include<vector>
#include<set>
#include<algorithm>

int n;

long double X0,Y0;
int M;

struct Point{
	long double X,Y;
	Point(){X=Y=0;}
	Point(long double X_,long double Y_){X=X_,Y=Y_;}
};
struct Circle{
	Point O;
	long double R;
	Circle(){R=0;}
	Circle(const Point &O_,long double R_){O=O_,R=R_;}
};
struct Line{ // y=kx+b
	long double K,B;
	Line(){K=B=0;}
	Line(long double K_,long double B_){K=K_,B=B_;}
}L[50050];

inline long double sqr(long double k){return k*k;}
inline long double distance(const Point &A,const Point &B){return sqrtl(sqr(A.X-B.X)+sqr(A.Y-B.Y));}
inline long double distance(const Point &P,const Line &L){
	long double X=(P.Y+P.X/L.K-L.B)/(L.K+1/L.K);
	return distance(P,Point(X,X*L.K+L.B));
}
std::pair<bool,std::pair<long double,long double> > checkIntersection(const Circle &C,const Line &L){
//	long double dis=distance(C.O,L);
//	if (dis>C.R) return std::make_pair(false,std::make_pair(0,0));
	long double P=1+sqr(L.K),Q=-2*C.O.X+2*L.K*(L.B-C.O.Y),R=sqr(C.O.X)+sqr(L.B-C.O.Y)-sqr(C.R);
	long double delta=sqr(Q)-4*P*R;
//	std::cout<<"delta="<<delta<<std::endl;
	if (delta<0) return std::make_pair(false,std::make_pair(0,0));
//	assert(delta>=0);
	delta=sqrtl(delta);
	long double X1=(-Q+delta)/(2*P),X2=(-Q-delta)/(2*P);
	long double Y1=L.K*X1+L.B,Y2=L.K*X2+L.B;
	return std::make_pair(true,std::make_pair(atan2l(Y1-C.O.Y,X1-C.O.X),atan2l(Y2-C.O.Y,X2-C.O.X)));
}
Point Intersection(const Line &A,const Line &B){
	long double X=-(A.B-B.B)/(A.K-B.K);
	return Point(X,A.K*X+A.B);
}

const long double eps=1e-8;

int pos[50050],rpos[50050];

struct Fenwick{
	int F[100050],flim;
	void mark(int v){while (v<=flim) F[v]++,v+=v&-v;}
	void remark(int v){while (v<=flim) F[v]--,v+=v&-v;}
	int query(int v){int ret=0;while (v) ret+=F[v],v&=v-1;return ret;}
	int query(int l,int r){return query(r)-query(l-1);}
	void clear(){memset(F,0,sizeof(F));}
}F;

int countInnerPoints(long double rad){
	std::vector<std::pair<long double,int> > PV;
	Circle nowC=Circle(Point(X0,Y0),rad);
	for (int i=1;i<=n;i++){
		auto res=checkIntersection(nowC,L[i]);
		if (!res.first) continue;
		PV.push_back(std::make_pair(res.second.first,i));
		PV.push_back(std::make_pair(res.second.second,i));
	}
	std::sort(PV.begin(),PV.end());
	int ans=0;
	F.flim=PV.size();
	for (int i=0;i<PV.size();i++){
		if (pos[PV[i].second]){
			ans+=F.query(pos[PV[i].second]+1,i);
			F.remark(pos[PV[i].second]);
//			printf("remark %d\n",pos[PV[i].second]);
			pos[PV[i].second]=0;
		}
		else{
			F.mark(i+1);
//			printf("mark %d\n",i+1);
			pos[PV[i].second]=i+1;
		}
	}
	return ans;
}

long double finalcalc(long double rad){
	std::vector<std::pair<long double,int> > PV;
	Circle nowC=Circle(Point(X0,Y0),rad);
	for (int i=1;i<=n;i++){
		auto res=checkIntersection(nowC,L[i]);
		if (!res.first) continue;
		PV.push_back(std::make_pair(res.second.first,i));
		PV.push_back(std::make_pair(res.second.second,i));
	}
	std::sort(PV.begin(),PV.end());
	std::set<int> F;
	long double result=0;
	for (int i=0;i<PV.size();i++){
		if (pos[PV[i].second]){
			auto it=F.lower_bound(pos[PV[i].second]);
			for (auto t=std::next(it);t!=F.end();++t){
//				printf("%d with %d\n",PV[i].second,*t);
				result+=distance(Intersection(L[rpos[*t]],L[PV[i].second]),Point(X0,Y0));
			}
			F.erase(it);
//			std::cout<<"erase "<<*it<<std::endl;
			pos[PV[i].second]=0;
		}
		else{
			rpos[pos[PV[i].second]=i+1]=PV[i].second;
			F.insert(i+1);
//			std::cout<<"insert "<<i+1<<std::endl;
		}
	}
	return result;
}

int main(){
	scanf("%d",&n);
	scanf("%Lf%Lf%d",&X0,&Y0,&M);
	for (int i=1,x,y;i<=n;i++) scanf("%d%d",&x,&y),L[i]=Line(x/1000.,y/1000.);

	X0/=1000,Y0/=1000;

	long double L=0,R=1e20;
	while (R-L>eps){
		long double mdl=(L+R)/2;
//		std::cout<<"mdl="<<mdl<<std::endl;
		int count=countInnerPoints(mdl);
		if (count>=M) R=mdl;
		else L=mdl;
	}
	int finalcount=countInnerPoints(L-eps);
	printf("%.12Lf\n",finalcalc(L-eps)+(M-finalcount)*L);
}


#include <cstdio>
#include <algorithm>
#include <cmath>
int N, M, _X, _Y, L, T[262144], ID[262144], HL, ql[50001], qr[50001];
struct point
{
	long double x, y;
}
p[50001];
struct angle
{
	int side;
	long double ik;
}
H[100001];
inline bool operator < (const angle &a, const angle &b)
{
	return a.side < b.side || (a.side == b.side && a.ik > b.ik);
}
inline bool operator == (const angle &a, const angle &b)
{
	return !(a < b) && !(b < a);
}
std::pair < std::pair < angle, angle >, int > q[50001];
void build(int p, int l, int r)
{
	T[p] = 0;
	if (l < r)
	{
		int m = (l + r) >> 1;
		build(p << 1, l, m);
		build(p << 1 | 1, m + 1, r);
	}
}
void P(int x, int y)
{
	int p = 1, l = 1, r = HL;
	T[p]++;
	while (l < r)
	{
		int m = (l + r) >> 1;
		if (x <= m)
			p <<= 1, r = m;
		else
			p = p << 1 | 1, l = m + 1;
		T[p]++;
	}
	ID[p] = y;
}
int G(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R)
		return T[p];
	int m = (l + r) >> 1;
	if (R <= m)
		return G(p << 1, l, m, L, R);
	if (L > m)
		return G(p << 1 | 1, m + 1, r, L, R);
	return G(p << 1, l, m, L, R) + G(p << 1 | 1, m + 1, r, L, R);
}
long double dis(int u, int v)
{
	long double x = (p[u].y - p[v].y) / (p[v].x - p[u].x), y = x * p[u].x + p[u].y;
	return sqrt(x * x + y * y);
}
long double list(int p, int l, int r, int L, int R, int start)
{
	if (!T[p])
		return 0;
	if (l == r)
		return T[p] ? dis(start, ID[p]) : 0;
	int m = (l + r) >> 1;
	if (R <= m)
		return list(p << 1, l, m, L, R, start);
	if (L > m)
		return list(p << 1 | 1, m + 1, r, L, R, start);
	return list(p << 1, l, m, L, R, start) + list(p << 1 | 1, m + 1, r, L, R, start);
}
std::pair < int, long double > F(long double R, int tag)
{
	L = 0;
	for (int i = 1; i <= N; i++)
	{
		long double delta = (p[i].x * p[i].x + 1) * R * R - p[i].y * p[i].y;
		if (delta >= 0)
		{
			delta = sqrt(delta);
			long double x0 = (-p[i].x * p[i].y + delta) / (p[i].x * p[i].x + 1), y0 = x0 * p[i].x + p[i].y;
			long double x1 = (-p[i].x * p[i].y - delta) / (p[i].x * p[i].x + 1), y1 = x1 * p[i].x + p[i].y;
			q[++L] = { { { y0 ? (y0 < 0 ? 3 : 1) : (x0 > 0 ? 2 : 0), y0 ? x0 / y0 : 0 }, { y1 ? (y1 < 0 ? 3 : 1) : (x1 > 0 ? 2 : 0), y1 ? x1 / y1 : 0 } }, i };
			if (q[L].first.second < q[L].first.first)
				std::swap(q[L].first.first, q[L].first.second);
		}
	}
	for (int i = 1; i <= L; i++)
	{
		H[i] = q[i].first.first;
		H[L + i] = q[i].first.second;
	}
	std::sort(H + 1, H + L + L + 1);
	HL = std::unique(H + 1, H + L + L + 1) - H;
	build(1, 1, HL);
	std::sort(q + 1, q + L + 1);
	int count = 0;
	for (int i = 1; i <= L; i++)
	{
		ql[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.first) - H;
		qr[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.second) - H;
		count += G(1, 1, HL, ql[i], qr[i]);
		P(qr[i], q[i].second);
	}
	if (count == M || (count < M && tag))
	{
		build(1, 1, HL);
		long double SUM = 0;
		for (int i = 1; i <= L; i++)
		{
			SUM += list(1, 1, HL, ql[i], qr[i], q[i].second);
			P(qr[i], q[i].second);
		}
		return { count, SUM };
	}
	else
		return { count, 0 };
}
int main()
{
	scanf("%d%d%d%d", &N, &_X, &_Y, &M);
	for (int i = 1, K, B; i <= N; i++)
	{
		scanf("%d%d", &K, &B);
		p[i].x = K / 1000.0L;
		p[i].y = (B - _Y) / 1000.0L + (long double)K * _X / 1000000.0L;
	}
	long double l = 0, r = 1e12;
	while (1)
	{
		long double m = (l + r) / 2;
		std::pair < int, long double > f = F(m, r - l < 1e-6);
		if (f.first == M || (f.first < M && r - l < 1e-6))
		{
			printf("%.10Lf\n", f.second + (M - f.first) * l);
			return 0;
		}
		if (m < 1e-13 && f.first > M)
		{
			puts("0.0000000000");
			return 0;
		}
		(f.first < M ? l : r) = m;
	}
}


#include <cstdio>
#include <algorithm>
#include <cmath>
int N, M, _X, _Y, L, T[262144], ID[262144], HL, ql[50001], qr[50001];
struct point
{
	long double x, y;
}
p[50001];
struct angle
{
	int side;
	long double ik;
}
H[100001];
inline bool operator < (const angle &a, const angle &b)
{
	return a.side < b.side || (a.side == b.side && a.ik > b.ik);
}
inline bool operator == (const angle &a, const angle &b)
{
	return !(a < b) && !(b < a);
}
std::pair < std::pair < angle, angle >, int > q[50001];
void build(int p, int l, int r)
{
	T[p] = 0;
	if (l < r)
	{
		int m = (l + r) >> 1;
		build(p << 1, l, m);
		build(p << 1 | 1, m + 1, r);
	}
}
void P(int x, int y)
{
	int p = 1, l = 1, r = HL;
	T[p]++;
	while (l < r)
	{
		int m = (l + r) >> 1;
		if (x <= m)
			p <<= 1, r = m;
		else
			p = p << 1 | 1, l = m + 1;
		T[p]++;
	}
	ID[p] = y;
}
int G(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R)
		return T[p];
	int m = (l + r) >> 1;
	if (R <= m)
		return G(p << 1, l, m, L, R);
	if (L > m)
		return G(p << 1 | 1, m + 1, r, L, R);
	return G(p << 1, l, m, L, R) + G(p << 1 | 1, m + 1, r, L, R);
}
long double dis(int u, int v)
{
	long double x = (p[u].y - p[v].y) / (p[v].x - p[u].x), y = x * p[u].x + p[u].y;
	return sqrt(x * x + y * y);
}
long double list(int p, int l, int r, int L, int R, int start)
{
	if (!T[p])
		return 0;
	if (l == r)
		return T[p] ? dis(start, ID[p]) : 0;
	int m = (l + r) >> 1;
	if (R <= m)
		return list(p << 1, l, m, L, R, start);
	if (L > m)
		return list(p << 1 | 1, m + 1, r, L, R, start);
	return list(p << 1, l, m, L, R, start) + list(p << 1 | 1, m + 1, r, L, R, start);
}
std::pair < int, long double > F(long double R)
{
	L = 0;
	for (int i = 1; i <= N; i++)
	{
		long double delta = (p[i].x * p[i].x + 1) * R * R - p[i].y * p[i].y;
		if (delta >= 0)
		{
			delta = sqrt(delta);
			long double x0 = (-p[i].x * p[i].y + delta) / (p[i].x * p[i].x + 1), y0 = x0 * p[i].x + p[i].y;
			long double x1 = (-p[i].x * p[i].y - delta) / (p[i].x * p[i].x + 1), y1 = x1 * p[i].x + p[i].y;
			q[++L] = { { { y0 ? (y0 < 0 ? 3 : 1) : (x0 > 0 ? 2 : 0), y0 ? x0 / y0 : 0 }, { y1 ? (y1 < 0 ? 3 : 1) : (x1 > 0 ? 2 : 0), y1 ? x1 / y1 : 0 } }, i };
			if (q[L].first.second < q[L].first.first)
				std::swap(q[L].first.first, q[L].first.second);
		}
	}
	for (int i = 1; i <= L; i++)
	{
		H[i] = q[i].first.first;
		H[L + i] = q[i].first.second;
	}
	std::sort(H + 1, H + L + L + 1);
	HL = std::unique(H + 1, H + L + L + 1) - H;
	build(1, 1, HL);
	std::sort(q + 1, q + L + 1);
	int count = 0;
	for (int i = 1; i <= L; i++)
	{
		ql[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.first) - H;
		qr[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.second) - H;
		count += G(1, 1, HL, ql[i], qr[i]);
		P(qr[i], q[i].second);
	}
	if (count == M)
	{
		build(1, 1, HL);
		long double SUM = 0;
		for (int i = 1; i <= L; i++)
		{
			SUM += list(1, 1, HL, ql[i], qr[i], q[i].second);
			P(qr[i], q[i].second);
		}
		return { count, SUM };
	}
	else
		return { count, 0 };
}
int main()
{
	scanf("%d%d%d%d", &N, &_X, &_Y, &M);
	for (int i = 1, K, B; i <= N; i++)
	{
		scanf("%d%d", &K, &B);
		p[i].x = K / 1000.0L;
		p[i].y = (B - _Y) / 1000.0L + (long double)K * _X / 1000000.0L;
	}
	long double l = 0, r = 1e9;
	while (1)
	{
		long double m = (l + r) / 2;
		std::pair < int, long double > f = F(m);
		if (f.first == M)
		{
			printf("%.10Lf\n", f.second);
			return 0;
		}
		(f.first < M ? l : r) = m;
	}
}


#include <cstdio>
#include <algorithm>
#include <cmath>
int N, M, _X, _Y, L, T[262144], ID[262144], HL, ql[50001], qr[50001];
struct point
{
	long double x, y;
}
p[50001];
struct angle
{
	int side;
	long double ik;
}
H[100001];
inline bool operator < (const angle &a, const angle &b)
{
	return a.side < b.side || (a.side == b.side && a.ik > b.ik);
}
inline bool operator == (const angle &a, const angle &b)
{
	return !(a < b) && !(b < a);
}
std::pair < std::pair < angle, angle >, int > q[50001];
void build(int p, int l, int r)
{
	T[p] = 0;
	if (l < r)
	{
		int m = (l + r) >> 1;
		build(p << 1, l, m);
		build(p << 1 | 1, m + 1, r);
	}
}
void P(int x, int y)
{
	int p = 1, l = 1, r = HL;
	T[p]++;
	while (l < r)
	{
		int m = (l + r) >> 1;
		if (x <= m)
			p <<= 1, r = m;
		else
			p = p << 1 | 1, l = m + 1;
		T[p]++;
	}
	ID[p] = y;
}
int G(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R)
		return T[p];
	int m = (l + r) >> 1;
	if (R <= m)
		return G(p << 1, l, m, L, R);
	if (L > m)
		return G(p << 1 | 1, m + 1, r, L, R);
	return G(p << 1, l, m, L, R) + G(p << 1 | 1, m + 1, r, L, R);
}
long double dis(int u, int v)
{
	long double x = (p[u].y - p[v].y) / (p[v].x - p[u].x), y = x * p[u].x + p[u].y;
	return sqrt(x * x + y * y);
}
long double list(int p, int l, int r, int L, int R, int start)
{
	if (!T[p])
		return 0;
	if (l == r)
		return T[p] ? dis(start, ID[p]) : 0;
	int m = (l + r) >> 1;
	if (R <= m)
		return list(p << 1, l, m, L, R, start);
	if (L > m)
		return list(p << 1 | 1, m + 1, r, L, R, start);
	return list(p << 1, l, m, L, R, start) + list(p << 1 | 1, m + 1, r, L, R, start);
}
std::pair < int, long double > F(long double R)
{
	L = 0;
	for (int i = 1; i <= N; i++)
	{
		long double delta = (p[i].x * p[i].x + 1) * R * R - p[i].y * p[i].y;
		if (delta >= 0)
		{
			delta = sqrt(delta);
			long double x0 = (-p[i].x * p[i].y + delta) / (p[i].x * p[i].x + 1), y0 = x0 * p[i].x + p[i].y;
			long double x1 = (-p[i].x * p[i].y - delta) / (p[i].x * p[i].x + 1), y1 = x1 * p[i].x + p[i].y;
			q[++L] = { { { y0 ? (y0 < 0 ? 3 : 1) : (x0 > 0 ? 2 : 0), y0 ? x0 / y0 : 0 }, { y1 ? (y1 < 0 ? 3 : 1) : (x1 > 0 ? 2 : 0), y1 ? x1 / y1 : 0 } }, i };
			if (q[L].first.second < q[L].first.first)
				std::swap(q[L].first.first, q[L].first.second);
		}
	}
	for (int i = 1; i <= L; i++)
	{
		H[i] = q[i].first.first;
		H[L + i] = q[i].first.second;
	}
	std::sort(H + 1, H + L + L + 1);
	HL = std::unique(H + 1, H + L + L + 1) - H;
	build(1, 1, HL);
	std::sort(q + 1, q + L + 1);
	int count = 0;
	for (int i = 1; i <= L; i++)
	{
		ql[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.first) - H;
		qr[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.second) - H;
		count += G(1, 1, HL, ql[i], qr[i]);
		P(qr[i], q[i].second);
	}
	if (count == M)
	{
		build(1, 1, HL);
		long double SUM = 0;
		for (int i = 1; i <= L; i++)
		{
			SUM += list(1, 1, HL, ql[i], qr[i], q[i].second);
			P(qr[i], q[i].second);
		}
		return { count, SUM };
	}
	else
		return { count, 0 };
}
int main()
{
	scanf("%d%d%d%d", &N, &_X, &_Y, &M);
	for (int i = 1, K, B; i <= N; i++)
	{
		scanf("%d%d", &K, &B);
		p[i].x = K / 1000.0L;
		p[i].y = (B - _Y) / 1000.0L + (long double)K * _X / 1000000.0L;
	}
	long double l = 0, r = 1e12;
	while (1)
	{
		long double m = (l + r) / 2;
		std::pair < int, long double > f = F(m);
		if (f.first == M)
		{
			printf("%.10Lf\n", f.second);
			return 0;
		}
		(f.first < M ? l : r) = m;
	}
}


#include <cstdio>
#include <algorithm>
#include <cmath>
int N, M, _X, _Y, L, T[262144], ID[262144], HL, ql[50001], qr[50001];
struct point
{
	long double x, y;
}
p[50001];
struct angle
{
	int side;
	long double ik;
}
H[100001];
inline bool operator < (const angle &a, const angle &b)
{
	return a.side < b.side || (a.side == b.side && a.ik > b.ik);
}
inline bool operator == (const angle &a, const angle &b)
{
	return !(a < b) && !(b < a);
}
std::pair < std::pair < angle, angle >, int > q[50001];
void build(int p, int l, int r)
{
	T[p] = 0;
	if (l < r)
	{
		int m = (l + r) >> 1;
		build(p << 1, l, m);
		build(p << 1 | 1, m + 1, r);
	}
}
void P(int x, int y)
{
	int p = 1, l = 1, r = HL;
	T[p]++;
	while (l < r)
	{
		int m = (l + r) >> 1;
		if (x <= m)
			p <<= 1, r = m;
		else
			p = p << 1 | 1, l = m + 1;
		T[p]++;
	}
	ID[p] = y;
}
int G(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R)
		return T[p];
	int m = (l + r) >> 1;
	if (R <= m)
		return G(p << 1, l, m, L, R);
	if (L > m)
		return G(p << 1 | 1, m + 1, r, L, R);
	return G(p << 1, l, m, L, R) + G(p << 1 | 1, m + 1, r, L, R);
}
long double dis(int u, int v)
{
	long double x = (p[u].y - p[v].y) / (p[v].x - p[u].x), y = x * p[u].x + p[u].y;
	return sqrt(x * x + y * y);
}
long double list(int p, int l, int r, int L, int R, int start)
{
	if (!T[p])
		return 0;
	if (l == r)
		return T[p] ? dis(start, ID[p]) : 0;
	int m = (l + r) >> 1;
	if (R <= m)
		return list(p << 1, l, m, L, R, start);
	if (L > m)
		return list(p << 1 | 1, m + 1, r, L, R, start);
	return list(p << 1, l, m, L, R, start) + list(p << 1 | 1, m + 1, r, L, R, start);
}
std::pair < int, long double > F(long double R)
{
	L = 0;
	for (int i = 1; i <= N; i++)
	{
		long double delta = (p[i].x * p[i].x + 1) * R * R - p[i].y * p[i].y;
		if (delta >= 0)
		{
			long double x0 = (-p[i].x * p[i].y + delta) / (p[i].x * p[i].x + 1), y0 = x0 * p[i].x + p[i].y;
			long double x1 = (-p[i].x * p[i].y - delta) / (p[i].x * p[i].x + 1), y1 = x1 * p[i].x + p[i].y;
			q[++L] = { { { y0 ? (y0 < 0 ? 3 : 1) : (x0 > 0 ? 2 : 0), y0 ? x0 / y0 : 0 }, { y1 ? (y1 < 0 ? 3 : 1) : (x1 > 0 ? 2 : 0), y1 ? x1 / y1 : 0 } }, i };
			if (q[L].first.second < q[L].first.first)
				std::swap(q[L].first.first, q[L].first.second);
		}
	}
	for (int i = 1; i <= L; i++)
	{
		H[i] = q[i].first.first;
		H[L + i] = q[i].first.second;
	}
	std::sort(H + 1, H + L + L + 1);
	HL = std::unique(H + 1, H + L + L + 1) - H;
	build(1, 1, HL);
	std::sort(q + 1, q + L + 1);
	int count = 0;
	for (int i = 1; i <= L; i++)
	{
		ql[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.first) - H;
		qr[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.second) - H;
		count += G(1, 1, HL, ql[i], qr[i]);
		P(qr[i], q[i].second);
	}
	if (count == M)
	{
		build(1, 1, HL);
		long double SUM = 0;
		for (int i = 1; i <= L; i++)
		{
			SUM += list(1, 1, HL, ql[i], qr[i], q[i].second);
			P(qr[i], q[i].second);
		}
		return { count, SUM };
	}
	else
		return { count, 0 };
}
int main()
{
	scanf("%d%d%d%d", &N, &_X, &_Y, &M);
	for (int i = 1, K, B; i <= N; i++)
	{
		scanf("%d%d", &K, &B);
		p[i].x = K / 1000.0L;
		p[i].y = (B - _Y) / 1000.0L + (long double)K * _X / 1000000.0L;
	}
	long double l = 0, r = 1e9;
	while (1)
	{
		long double m = (l + r) / 2;
		std::pair < int, long double > f = F(m);
		if (f.first == M)
		{
			printf("%.10Lf\n", f.second);
			return 0;
		}
		(f.first < M ? l : r) = m;
	}
}


#include <cstdio>
#include <algorithm>
#include <cmath>
int N, M, _X, _Y, L, T[262144], ID[262144], HL, ql[50001], qr[50001];
struct point
{
	long double x, y;
}
p[50001];
struct angle
{
	int side;
	long double ik;
}
H[100001];
inline bool operator < (const angle &a, const angle &b)
{
	return a.side < b.side || (a.side == b.side && a.ik > b.ik);
}
inline bool operator == (const angle &a, const angle &b)
{
	return !(a < b) && !(b < a);
}
std::pair < std::pair < angle, angle >, int > q[50001];
void build(int p, int l, int r)
{
	T[p] = 0;
	if (l < r)
	{
		int m = (l + r) >> 1;
		build(p << 1, l, m);
		build(p << 1 | 1, m + 1, r);
	}
}
void P(int x, int y)
{
	int p = 1, l = 1, r = HL;
	T[p]++;
	while (l < r)
	{
		int m = (l + r) >> 1;
		if (x <= m)
			p <<= 1, r = m;
		else
			p = p << 1 | 1, l = m + 1;
		T[p]++;
	}
	ID[p] = y;
}
int G(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R)
		return T[p];
	int m = (l + r) >> 1;
	if (R <= m)
		return G(p << 1, l, m, L, R);
	if (L > m)
		return G(p << 1 | 1, m + 1, r, L, R);
	return G(p << 1, l, m, L, R) + G(p << 1 | 1, m + 1, r, L, R);
}
long double dis(int u, int v)
{
	long double x = (p[u].y - p[v].y) / (p[v].x - p[u].x), y = x * p[u].x + p[u].y;
	return sqrt(x * x + y * y);
}
long double list(int p, int l, int r, int L, int R, int start)
{
	if (!T[p])
		return 0;
	if (l == r)
		return T[p] ? dis(start, ID[p]) : 0;
	int m = (l + r) >> 1;
	if (R <= m)
		return list(p << 1, l, m, L, R, start);
	if (L > m)
		return list(p << 1 | 1, m + 1, r, L, R, start);
	return list(p << 1, l, m, L, R, start) + list(p << 1 | 1, m + 1, r, L, R, start);
}
std::pair < int, long double > F(long double R, int tag)
{
	L = 0;
	for (int i = 1; i <= N; i++)
	{
		long double delta = (p[i].x * p[i].x + 1) * R * R - p[i].y * p[i].y;
		if (delta >= 0)
		{
			delta = sqrt(delta);
			long double x0 = (-p[i].x * p[i].y + delta) / (p[i].x * p[i].x + 1), y0 = x0 * p[i].x + p[i].y;
			long double x1 = (-p[i].x * p[i].y - delta) / (p[i].x * p[i].x + 1), y1 = x1 * p[i].x + p[i].y;
			q[++L] = { { { y0 ? (y0 < 0 ? 3 : 1) : (x0 > 0 ? 2 : 0), y0 ? x0 / y0 : 0 }, { y1 ? (y1 < 0 ? 3 : 1) : (x1 > 0 ? 2 : 0), y1 ? x1 / y1 : 0 } }, i };
			if (q[L].first.second < q[L].first.first)
				std::swap(q[L].first.first, q[L].first.second);
		}
	}
	for (int i = 1; i <= L; i++)
	{
		H[i] = q[i].first.first;
		H[L + i] = q[i].first.second;
	}
	std::sort(H + 1, H + L + L + 1);
	HL = std::unique(H + 1, H + L + L + 1) - H;
	build(1, 1, HL);
	std::sort(q + 1, q + L + 1);
	int count = 0;
	for (int i = 1; i <= L; i++)
	{
		ql[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.first) - H;
		qr[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.second) - H;
		count += G(1, 1, HL, ql[i], qr[i]);
		P(qr[i], q[i].second);
	}
	if (count == M || (count < M && tag))
	{
		build(1, 1, HL);
		long double SUM = 0;
		for (int i = 1; i <= L; i++)
		{
			SUM += list(1, 1, HL, ql[i], qr[i], q[i].second);
			P(qr[i], q[i].second);
		}
		return { count, SUM };
	}
	else
		return { count, 0 };
}
int main()
{
	scanf("%d%d%d%d", &N, &_X, &_Y, &M);
	for (int i = 1, K, B; i <= N; i++)
	{
		scanf("%d%d", &K, &B);
		p[i].x = K / 1000.0L;
		p[i].y = (B - _Y) / 1000.0L + (long double)K * _X / 1000000.0L;
	}
	long double l = 0, r = 1e12;
	while (1)
	{
		long double m = (l + r) / 2;
		std::pair < int, long double > f = F(m, r - l < 1e-6);
		if (f.first == M || (f.first < M && r - l < 1e-6))
		{
			printf("%.10Lf\n", f.second + (M - f.first) * l);
			return 0;
		}
		(f.first < M ? l : r) = m;
	}
}


#include <cstdio>
#include <algorithm>
#include <cmath>
int N, M, _X, _Y, L, T[262144], ID[262144], HL, ql[50001], qr[50001];
struct point
{
	long double x, y;
}
p[50001];
struct angle
{
	int side;
	long double ik;
}
H[100001];
inline bool operator < (const angle &a, const angle &b)
{
	return a.side < b.side || (a.side == b.side && a.ik > b.ik);
}
inline bool operator == (const angle &a, const angle &b)
{
	return !(a < b) && !(b < a);
}
std::pair < std::pair < angle, angle >, int > q[50001];
void build(int p, int l, int r)
{
	T[p] = 0;
	if (l < r)
	{
		int m = (l + r) >> 1;
		build(p << 1, l, m);
		build(p << 1 | 1, m + 1, r);
	}
}
void P(int x, int y)
{
	int p = 1, l = 1, r = HL;
	T[p]++;
	while (l < r)
	{
		int m = (l + r) >> 1;
		if (x <= m)
			p <<= 1, r = m;
		else
			p = p << 1 | 1, l = m + 1;
		T[p]++;
	}
	ID[p] = y;
}
int G(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R)
		return T[p];
	int m = (l + r) >> 1;
	if (R <= m)
		return G(p << 1, l, m, L, R);
	if (L > m)
		return G(p << 1 | 1, m + 1, r, L, R);
	return G(p << 1, l, m, L, R) + G(p << 1 | 1, m + 1, r, L, R);
}
long double dis(int u, int v)
{
	long double x = (p[u].y - p[v].y) / (p[v].x - p[u].x), y = x * p[u].x + p[u].y;
	return sqrt(x * x + y * y);
}
long double list(int p, int l, int r, int L, int R, int start)
{
	if (!T[p])
		return 0;
	if (l == r)
		return T[p] ? dis(start, ID[p]) : 0;
	int m = (l + r) >> 1;
	if (R <= m)
		return list(p << 1, l, m, L, R, start);
	if (L > m)
		return list(p << 1 | 1, m + 1, r, L, R, start);
	return list(p << 1, l, m, L, R, start) + list(p << 1 | 1, m + 1, r, L, R, start);
}
std::pair < int, long double > F(long double R)
{
	L = 0;
	for (int i = 1; i <= N; i++)
	{
		long double delta = (p[i].x * p[i].x + 1) * R * R - p[i].y * p[i].y;
		if (delta >= 0)
		{
			delta = sqrt(delta);
			long double x0 = (-p[i].x * p[i].y + delta) / (p[i].x * p[i].x + 1), y0 = x0 * p[i].x + p[i].y;
			long double x1 = (-p[i].x * p[i].y - delta) / (p[i].x * p[i].x + 1), y1 = x1 * p[i].x + p[i].y;
			q[++L] = { { { y0 ? (y0 < 0 ? 3 : 1) : (x0 > 0 ? 2 : 0), y0 ? x0 / y0 : 0 }, { y1 ? (y1 < 0 ? 3 : 1) : (x1 > 0 ? 2 : 0), y1 ? x1 / y1 : 0 } }, i };
			if (q[L].first.second < q[L].first.first)
				std::swap(q[L].first.first, q[L].first.second);
		}
	}
	for (int i = 1; i <= L; i++)
	{
		H[i] = q[i].first.first;
		H[L + i] = q[i].first.second;
	}
	std::sort(H + 1, H + L + L + 1);
	HL = std::unique(H + 1, H + L + L + 1) - H;
	build(1, 1, HL);
	std::sort(q + 1, q + L + 1);
	int count = 0;
	for (int i = 1; i <= L; i++)
	{
		ql[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.first) - H;
		qr[i] = std::lower_bound(H + 1, H + HL + 1, q[i].first.second) - H;
		count += G(1, 1, HL, ql[i], qr[i]);
		P(qr[i], q[i].second);
	}
	if (count == M)
	{
		build(1, 1, HL);
		long double SUM = 0;
		for (int i = 1; i <= L; i++)
		{
			SUM += list(1, 1, HL, ql[i], qr[i], q[i].second);
			P(qr[i], q[i].second);
		}
		return { count, SUM };
	}
	else
		return { count, 0 };
}
int main()
{
	scanf("%d%d%d%d", &N, &_X, &_Y, &M);
	for (int i = 1, K, B; i <= N; i++)
	{
		scanf("%d%d", &K, &B);
		p[i].x = K / 1000.0L;
		p[i].y = (B - _Y) / 1000.0L + (long double)K * _X / 1000000.0L;
	}
	long double l = 0, r = 1e12;
	for (int  i = 10; i--; )
	{
		long double m = (l + r) / 2;
		std::pair < int, long double > f = F(m);
		if (f.first == M)
		{
			printf("%.10Lf\n", f.second);
			return 0;
		}
		(f.first < M ? l : r) = m;
	}
}


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

typedef long double ld;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

struct triple {
	ld l, r;
	int id;
	bool operator <(const triple &rhs) const {
		if (l != rhs.l)
			return l < rhs.l;
		return r > rhs.r;
	}
};

int N, M;
ld P, Q;
pair <ld, ld> L[MAXN];
vector <ld> all;
vector <triple> v;

ld dist(ld a1, ld b1, ld a2, ld b2) {
	ld x = (b2 - b1) / (a1 - a2);
	ld y = a1 * x + b1;
	return sqrt(x * x + y * y);
}

struct tournament {
	vector <int> pts[2 * offset];

	void init() {
		for (int i = 0; i < 2 * offset; i++)
			pts[i].clear();
	}

	void update(int x, int who) {
		for (x += offset; x; x /= 2)
			pts[x].push_back(who);
	}

	ld query(int x, int lo, int hi, int from, int to, int who) {
		if (lo >= to || hi <= from)
			return 0;
		if (lo >= from && hi <= to) {
			if (who == -1)
				return pts[x].size();
			ld res = 0;
			for (auto it : pts[x])
				res += dist(L[it].first, L[it].second, L[who].first, L[who].second);
			return res;
		}
		int mid = (lo + hi) / 2;
		return query(2 * x, lo, mid, from, to, who) + query(2 * x + 1, mid, hi, from, to, who);
	}
};

tournament T;

void scale(ld &x, ld &y) {
	x /= 1000;
	y /= 1000;
}

void load() {
	scanf("%d%Lf%Lf%d", &N, &P, &Q, &M);
	scale(P, Q);
	for (int i = 0; i < N; i++) {
		ld a, b;
		scanf("%Lf%Lf", &a, &b);
		scale(a, b);
		L[i] = {a, a * P + b - Q};
	}
}

void intersect(ld a, ld b, ld r, int who) {
	ld A = a * a + 1;
	ld B = 2 * a * b;
	ld C = b * b - r * r;
	ld D = B * B - 4 * A * C;
	if (D < 0)
		return;
	ld x1 = (-B + sqrt(D)) / (2 * A);
	ld x2 = (-B - sqrt(D)) / (2 * A);
	ld alpha1 = atan2(a * x1 + b, x1);
	ld alpha2 = atan2(a * x2 + b, x2);
	if (alpha1 > alpha2)
		swap(alpha1, alpha2);
	v.push_back({alpha1, alpha2, who});
	all.push_back(alpha1);
	all.push_back(alpha2);
}

void compress(ld &ref) {
	ref = lower_bound(all.begin(), all.end(), ref) - all.begin();
}

ld calc(ld r, bool sum = false) {
	T.init();
	all.clear();
	v.clear();
	for (int i = 0; i < N; i++)
		intersect(L[i].first, L[i].second, r, i);

	sort(all.begin(), all.end());

	for (auto &it : v) {
		compress(it.l);
		compress(it.r);
	}

	sort(v.begin(), v.end());

	ld res = 0;
	for (auto it : v) {
		res += T.query(1, 0, offset, it.l, it.r + 1, sum ? it.id : -1);
		T.update(it.r, it.id);
	}

	return res;
}

ld solve() {
	ld lo1 = 0, hi1 = 4e9;
	ld lo2 = 0, hi2 = 4e9;
	for (int it = 0; it < 150; it++) {
		ld mid1 = (lo1 + hi1) / 2;
		ld mid2 = (lo2 + hi2) / 2;
		if (calc(mid1) < M)
			lo1 = mid1;
		else
			hi1 = mid1;
		if (calc(mid2) >= M)
			hi2 = mid2;
		else
			lo2 = mid2;
	}

	return calc(lo1, true) + (M - calc(lo1)) * lo2;
}

int main() {
	load();
	printf("%.10Lf\n", solve());
	return 0;
}


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

typedef long double ld;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

struct triple {
	ld l, r;
	int id;
	bool operator <(const triple &rhs) const {
		if (l != rhs.l)
			return l < rhs.l;
		return r > rhs.r;
	}
};

int N, M;
ld P, Q;
pair <ld, ld> L[MAXN];
vector <ld> all;
vector <triple> v;

ld dist(ld a1, ld b1, ld a2, ld b2) {
	ld x = (b2 - b1) / (a1 - a2);
	ld y = a1 * x + b1;
	return sqrt(x * x + y * y);
}

struct tournament {
	int cnt[2 * offset];
	vector <int> pts[2 * offset];

	void init() {
		for (int i = 0; i < 2 * offset; i++) {
			pts[i].clear();
			cnt[i] = 0;
		}
	}

	void update(int x, int who) {
		if (who == -1) {
			for (x += offset; x; x /= 2)
				cnt[x]++;
			return;
		}
		for (x += offset; x; x /= 2)
			pts[x].push_back(who);
	}

	ld query(int x, int lo, int hi, int from, int to, int who) {
		if (lo >= to || hi <= from)
			return 0;
		if (lo >= from && hi <= to) {
			if (who == -1)
				return cnt[x];
			ld res = 0;
			for (auto it : pts[x])
				res += dist(L[it].first, L[it].second, L[who].first, L[who].second);
			return res;
		}
		int mid = (lo + hi) / 2;
		return query(2 * x, lo, mid, from, to, who) + query(2 * x + 1, mid, hi, from, to, who);
	}
};

tournament T;

void scale(ld &x, ld &y) {
	x /= 1000;
	y /= 1000;
}

void load() {
	scanf("%d%Lf%Lf%d", &N, &P, &Q, &M);
	scale(P, Q);
	for (int i = 0; i < N; i++) {
		ld a, b;
		scanf("%Lf%Lf", &a, &b);
		scale(a, b);
		L[i] = {a, a * P + b - Q};
	}
}

void intersect(ld a, ld b, ld r, int who) {
	ld A = a * a + 1;
	ld B = 2 * a * b;
	ld C = b * b - r * r;
	ld D = B * B - 4 * A * C;
	if (D < 0)
		return;
	ld x1 = (-B + sqrt(D)) / (2 * A);
	ld x2 = (-B - sqrt(D)) / (2 * A);
	ld alpha1 = atan2(a * x1 + b, x1);
	ld alpha2 = atan2(a * x2 + b, x2);
	if (alpha1 > alpha2)
		swap(alpha1, alpha2);
	v.push_back({alpha1, alpha2, who});
	all.push_back(alpha1);
	all.push_back(alpha2);
}

void compress(ld &ref) {
	ref = lower_bound(all.begin(), all.end(), ref) - all.begin();
}

ld calc(ld r, bool sum = false) {
	T.init();
	all.clear();
	v.clear();
	for (int i = 0; i < N; i++)
		intersect(L[i].first, L[i].second, r, i);

	sort(all.begin(), all.end());

	for (auto &it : v) {
		compress(it.l);
		compress(it.r);
	}

	sort(v.begin(), v.end());

	ld res = 0;
	for (auto it : v) {
		res += T.query(1, 0, offset, it.l, it.r + 1, sum ? it.id : -1);
		T.update(it.r, sum ? it.id : -1);
	}

	return res;
}

ld solve() {
	ld lo1 = 0, hi1 = 4e9;
	ld lo2 = 0, hi2 = 4e9;
	for (int it = 0; it < 150; it++) {
		ld mid1 = (lo1 + hi1) / 2;
		ld mid2 = (lo2 + hi2) / 2;
		if (calc(mid1) < M)
			lo1 = mid1;
		else
			hi1 = mid1;
		if (calc(mid2) >= M)
			hi2 = mid2;
		else
			lo2 = mid2;
	}

	return calc(lo1, true) + (M - calc(lo1)) * lo2;
}

int main() {
	load();
	printf("%.10Lf\n", solve());
	return 0;
}


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

typedef long double ld;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

struct triple {
	ld l, r;
	int id;
	bool operator <(const triple &rhs) const {
		if (l != rhs.l)
			return l < rhs.l;
		return r > rhs.r;
	}
};

int N, M;
ld P, Q;
pair <ld, ld> L[MAXN];
vector <ld> all;
vector <triple> v;

ld dist(ld a1, ld b1, ld a2, ld b2) {
	ld x = (b2 - b1) / (a1 - a2);
	ld y = a1 * x + b1;
	return sqrt(x * x + y * y);
}

struct tournament {
	int cnt[2 * offset];
	vector <int> pts[2 * offset];

	void init() {
		for (int i = 0; i < 2 * offset; i++) {
			pts[i].clear();
			cnt[i] = 0;
		}
	}

	void update(int x, int who) {
		if (who == -1) {
			for (x += offset; x; x /= 2)
				cnt[x]++;
			return;
		}
		for (x += offset; x; x /= 2)
			pts[x].push_back(who);
	}

	ld query(int x, int lo, int hi, int from, int to, int who) {
		if (lo >= to || hi <= from)
			return 0;
		if (lo >= from && hi <= to) {
			if (who == -1)
				return cnt[x];
			ld res = 0;
			for (auto it : pts[x])
				res += dist(L[it].first, L[it].second, L[who].first, L[who].second);
			return res;
		}
		int mid = (lo + hi) / 2;
		return query(2 * x, lo, mid, from, to, who) + query(2 * x + 1, mid, hi, from, to, who);
	}
};

tournament T;

void scale(ld &x, ld &y) {
	x /= 1000;
	y /= 1000;
}

void load() {
	scanf("%d%Lf%Lf%d", &N, &P, &Q, &M);
	scale(P, Q);
	for (int i = 0; i < N; i++) {
		ld a, b;
		scanf("%Lf%Lf", &a, &b);
		scale(a, b);
		L[i] = {a, a * P + b - Q};
	}
}

void intersect(ld a, ld b, ld r, int who) {
	ld A = a * a + 1;
	ld B = 2 * a * b;
	ld C = b * b - r * r;
	ld D = B * B - 4 * A * C;
	if (D < 0)
		return;
	ld x1 = (-B + sqrt(D)) / (2 * A);
	ld x2 = (-B - sqrt(D)) / (2 * A);
	ld alpha1 = atan2(a * x1 + b, x1);
	ld alpha2 = atan2(a * x2 + b, x2);
	if (alpha1 > alpha2)
		swap(alpha1, alpha2);
	v.push_back({alpha1, alpha2, who});
	all.push_back(alpha1);
	all.push_back(alpha2);
}

void compress(ld &ref) {
	ref = lower_bound(all.begin(), all.end(), ref) - all.begin();
}

ld calc(ld r, bool sum = false) {
	T.init();
	all.clear();
	v.clear();
	for (int i = 0; i < N; i++)
		intersect(L[i].first, L[i].second, r, i);

	sort(all.begin(), all.end());

	for (auto &it : v) {
		compress(it.l);
		compress(it.r);
	}

	sort(v.begin(), v.end());

	ld res = 0;
	for (auto it : v) {
		res += T.query(1, 0, offset, it.l, it.r + 1, sum ? it.id : -1);
		T.update(it.r, sum ? it.id : -1);
	}

	return res;
}

ld solve() {
	ld lo1 = 0, hi1 = 4e9;
	ld lo2 = 0, hi2 = 4e9;
	for (int it = 0; it < 60; it++) {
		ld mid1 = (lo1 + hi1) / 2;
		ld mid2 = (lo2 + hi2) / 2;
		if (calc(mid1) < M)
			lo1 = mid1;
		else
			hi1 = mid1;
		if (calc(mid2) >= M)
			hi2 = mid2;
		else
			lo2 = mid2;
	}

	return calc(lo1, true) + (M - calc(lo1)) * lo2;
}

int main() {
	load();
	printf("%.10Lf\n", solve());
	return 0;
}


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

typedef long double ld;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

struct triple {
	ld l, r;
	int id;
	bool operator <(const triple &rhs) const {
		if (l != rhs.l)
			return l < rhs.l;
		return r > rhs.r;
	}
};

int N, M;
ld P, Q;
pair <ld, ld> L[MAXN];
vector <ld> all;
vector <triple> v;

ld dist(ld a1, ld b1, ld a2, ld b2) {
	ld x = (b2 - b1) / (a1 - a2);
	ld y = a1 * x + b1;
	return sqrt(x * x + y * y);
}

struct tournament {
	vector <int> pts[2 * offset];

	void init() {
		for (int i = 0; i < 2 * offset; i++)
			pts[i].clear();
	}

	void update(int x, int who) {
		for (x += offset; x; x /= 2)
			pts[x].push_back(who);
	}

	ld query(int x, int lo, int hi, int from, int to, int who) {
		if (lo >= to || hi <= from)
			return 0;
		if (lo >= from && hi <= to) {
			if (who == -1)
				return pts[x].size();
			ld res = 0;
			for (auto it : pts[x])
				res += dist(L[it].first, L[it].second, L[who].first, L[who].second);
			return res;
		}
		int mid = (lo + hi) / 2;
		return query(2 * x, lo, mid, from, to, who) + query(2 * x + 1, mid, hi, from, to, who);
	}
};

tournament T;

void scale(ld &x, ld &y) {
	x /= 1000;
	y /= 1000;
}

void load() {
	scanf("%d%Lf%Lf%d", &N, &P, &Q, &M);
	scale(P, Q);
	for (int i = 0; i < N; i++) {
		ld a, b;
		scanf("%Lf%Lf", &a, &b);
		scale(a, b);
		L[i] = {a, a * P + b - Q};
	}
}

void intersect(ld a, ld b, ld r, int who) {
	ld A = a * a + 1;
	ld B = 2 * a * b;
	ld C = b * b - r * r;
	ld D = B * B - 4 * A * C;
	if (D < 0)
		return;
	ld x1 = (-B + sqrt(D)) / (2 * A);
	ld x2 = (-B - sqrt(D)) / (2 * A);
	ld alpha1 = atan2(a * x1 + b, x1);
	ld alpha2 = atan2(a * x2 + b, x2);
	if (alpha1 > alpha2)
		swap(alpha1, alpha2);
	v.push_back({alpha1, alpha2, who});
	all.push_back(alpha1);
	all.push_back(alpha2);
}

void compress(ld &ref) {
	ref = lower_bound(all.begin(), all.end(), ref) - all.begin();
}

ld calc(ld r, bool sum = false) {
	T.init();
	all.clear();
	v.clear();
	for (int i = 0; i < N; i++)
		intersect(L[i].first, L[i].second, r, i);

	sort(all.begin(), all.end());

	for (auto &it : v) {
		compress(it.l);
		compress(it.r);
	}

	sort(v.begin(), v.end());

	ld res = 0;
	for (auto it : v) {
		res += T.query(1, 0, offset, it.l, it.r + 1, sum ? it.id : -1);
		T.update(it.r, it.id);
	}

	return res;
}

ld solve() {
	ld lo1 = 0, hi1 = 4e9;
	ld lo2 = 0, hi2 = 4e9;
	for (int it = 0; it < 200; it++) {
		ld mid1 = (lo1 + hi1) / 2;
		ld mid2 = (lo2 + hi2) / 2;
		if (calc(mid1) < M)
			lo1 = mid1;
		else
			hi1 = mid1;
		if (calc(mid2) >= M)
			hi2 = mid2;
		else
			lo2 = mid2;
	}

	return calc(lo1, true) + (M - calc(lo1)) * lo2;
}

int main() {
	load();
	printf("%.10Lf\n", solve());
	return 0;
}


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

typedef long double ld;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

struct triple {
	ld l, r;
	int id;
	bool operator <(const triple &rhs) const {
		if (l != rhs.l)
			return l < rhs.l;
		return r > rhs.r;
	}
};

int N, M;
ld P, Q;
pair <ld, ld> L[MAXN];
vector <ld> all;
vector <triple> v;

ld dist(ld a1, ld b1, ld a2, ld b2) {
	ld x = (b2 - b1) / (a1 - a2);
	ld y = a1 * x + b1;
	return sqrt(x * x + y * y);
}

struct tournament {
	int cnt[2 * offset];
	vector <int> pts[2 * offset];

	void init() {
		for (int i = 0; i < 2 * offset; i++) {
			pts[i].clear();
			cnt[i] = 0;
		}
	}

	void update(int x, int who) {
		if (who == -1) {
			for (x += offset; x; x /= 2)
				cnt[x]++;
			return;
		}
		for (x += offset; x; x /= 2)
			pts[x].push_back(who);
	}

	ld query(int x, int lo, int hi, int from, int to, int who) {
		if (lo >= to || hi <= from)
			return 0;
		if (lo >= from && hi <= to) {
			if (who == -1)
				return cnt[x];
			ld res = 0;
			for (auto it : pts[x])
				res += dist(L[it].first, L[it].second, L[who].first, L[who].second);
			return res;
		}
		int mid = (lo + hi) / 2;
		return query(2 * x, lo, mid, from, to, who) + query(2 * x + 1, mid, hi, from, to, who);
	}
};

tournament T;

void scale(ld &x, ld &y) {
	x /= 1000;
	y /= 1000;
}

void load() {
	scanf("%d%Lf%Lf%d", &N, &P, &Q, &M);
	scale(P, Q);
	for (int i = 0; i < N; i++) {
		ld a, b;
		scanf("%Lf%Lf", &a, &b);
		scale(a, b);
		L[i] = {a, a * P + b - Q};
	}
}

void intersect(ld a, ld b, ld r, int who) {
	ld A = a * a + 1;
	ld B = 2 * a * b;
	ld C = b * b - r * r;
	ld D = B * B - 4 * A * C;
	if (D < 0)
		return;
	ld x1 = (-B + sqrt(D)) / (2 * A);
	ld x2 = (-B - sqrt(D)) / (2 * A);
	ld alpha1 = atan2(a * x1 + b, x1);
	ld alpha2 = atan2(a * x2 + b, x2);
	if (alpha1 > alpha2)
		swap(alpha1, alpha2);
	v.push_back({alpha1, alpha2, who});
	all.push_back(alpha1);
	all.push_back(alpha2);
}

void compress(ld &ref) {
	ref = lower_bound(all.begin(), all.end(), ref) - all.begin();
}

ld calc(ld r, bool sum = false) {
	T.init();
	all.clear();
	v.clear();
	for (int i = 0; i < N; i++)
		intersect(L[i].first, L[i].second, r, i);

	sort(all.begin(), all.end());

	for (auto &it : v) {
		compress(it.l);
		compress(it.r);
	}

	sort(v.begin(), v.end());

	ld res = 0;
	for (auto it : v) {
		res += T.query(1, 0, offset, it.l, it.r + 1, sum ? it.id : -1);
		T.update(it.r, sum ? it.id : -1);
	}

	return res;
}

ld solve() {
	ld lo1 = 0, hi1 = 4e9;
	ld lo2 = 0, hi2 = 4e9;
	for (int it = 0; it < 50; it++) {
		ld mid1 = (lo1 + hi1) / 2;
		ld mid2 = (lo2 + hi2) / 2;
		if (calc(mid1) < M)
			lo1 = mid1;
		else
			hi1 = mid1;
		if (calc(mid2) >= M)
			hi2 = mid2;
		else
			lo2 = mid2;
	}

	return calc(lo1, true) + (M - calc(lo1)) * lo2;
}

int main() {
	load();
	printf("%.10Lf\n", solve());
	return 0;
}


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

typedef long double ld;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

struct triple {
	ld l, r;
	int id;
	bool operator <(const triple &rhs) const {
		if (l != rhs.l)
			return l < rhs.l;
		return r > rhs.r;
	}
};

int N, M;
ld P, Q;
pair <ld, ld> L[MAXN];
vector <ld> all;
vector <triple> v;

ld dist(ld a1, ld b1, ld a2, ld b2) {
	ld x = (b2 - b1) / (a1 - a2);
	ld y = a1 * x + b1;
	return sqrt(x * x + y * y);
}

struct tournament {
	int cnt[2 * offset];
	vector <int> pts[2 * offset];

	void init() {
		for (int i = 0; i < 2 * offset; i++) {
			pts[i].clear();
			cnt[i] = 0;
		}
	}

	void update(int x, int who) {
		if (who == -1) {
			for (x += offset; x; x /= 2)
				cnt[x]++;
			return;
		}
		for (x += offset; x; x /= 2)
			pts[x].push_back(who);
	}

	ld query(int x, int lo, int hi, int from, int to, int who) {
		if (lo >= to || hi <= from)
			return 0;
		if (lo >= from && hi <= to) {
			if (who == -1)
				return cnt[x];
			ld res = 0;
			for (auto it : pts[x])
				res += dist(L[it].first, L[it].second, L[who].first, L[who].second);
			return res;
		}
		int mid = (lo + hi) / 2;
		return query(2 * x, lo, mid, from, to, who) + query(2 * x + 1, mid, hi, from, to, who);
	}
};

tournament T;

void scale(ld &x, ld &y) {
	x /= 1000;
	y /= 1000;
}

void load() {
	scanf("%d%Lf%Lf%d", &N, &P, &Q, &M);
	scale(P, Q);
	for (int i = 0; i < N; i++) {
		ld a, b;
		scanf("%Lf%Lf", &a, &b);
		scale(a, b);
		L[i] = {a, a * P + b - Q};
	}
}

void intersect(ld a, ld b, ld r, int who) {
	ld A = a * a + 1;
	ld B = 2 * a * b;
	ld C = b * b - r * r;
	ld D = B * B - 4 * A * C;
	if (D < 0)
		return;
	ld x1 = (-B + sqrt(D)) / (2 * A);
	ld x2 = (-B - sqrt(D)) / (2 * A);
	ld alpha1 = atan2(a * x1 + b, x1);
	ld alpha2 = atan2(a * x2 + b, x2);
	if (alpha1 > alpha2)
		swap(alpha1, alpha2);
	v.push_back({alpha1, alpha2, who});
	all.push_back(alpha1);
	all.push_back(alpha2);
}

void compress(ld &ref) {
	ref = lower_bound(all.begin(), all.end(), ref) - all.begin();
}

ld calc(ld r, bool sum = false) {
	T.init();
	all.clear();
	v.clear();
	for (int i = 0; i < N; i++)
		intersect(L[i].first, L[i].second, r, i);

	sort(all.begin(), all.end());

	for (auto &it : v) {
		compress(it.l);
		compress(it.r);
	}

	sort(v.begin(), v.end());

	ld res = 0;
	for (auto it : v) {
		res += T.query(1, 0, offset, it.l, it.r + 1, sum ? it.id : -1);
		T.update(it.r, sum ? it.id : -1);
	}

	return res;
}

ld solve() {
	ld lo1 = 0, hi1 = 4e9;
	ld lo2 = 0, hi2 = 4e9;
	for (int it = 0; it < 100; it++) {
		ld mid1 = (lo1 + hi1) / 2;
		ld mid2 = (lo2 + hi2) / 2;
		if (calc(mid1) < M)
			lo1 = mid1;
		else
			hi1 = mid1;
		if (calc(mid2) >= M)
			hi2 = mid2;
		else
			lo2 = mid2;
	}

	return calc(lo1, true) + (M - calc(lo1)) * lo2;
}

int main() {
	load();
	printf("%.10Lf\n", solve());
	return 0;
}


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

typedef long double ld;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

struct triple {
	ld l, r;
	int id;
	bool operator <(const triple &rhs) const {
		if (l != rhs.l)
			return l < rhs.l;
		return r > rhs.r;
	}
};

int N, M;
ld P, Q;
pair <ld, ld> L[MAXN];
vector <ld> all;
vector <triple> v;

ld dist(ld a1, ld b1, ld a2, ld b2) {
	ld x = (b2 - b1) / (a1 - a2);
	ld y = a1 * x + b1;
	return sqrt(x * x + y * y);
}

struct tournament {
	int cnt[2 * offset];
	vector <int> pts[2 * offset];

	void init() {
		for (int i = 0; i < 2 * offset; i++) {
			pts[i].clear();
			cnt[i] = 0;
		}
	}

	void update(int x, int who) {
		if (who == -1) {
			for (x += offset; x; x /= 2)
				cnt[x]++;
			return;
		}
		for (x += offset; x; x /= 2)
			pts[x].push_back(who);
	}

	ld query(int x, int lo, int hi, int from, int to, int who) {
		if (lo >= to || hi <= from)
			return 0;
		if (lo >= from && hi <= to) {
			if (who == -1)
				return cnt[x];
			ld res = 0;
			for (auto it : pts[x])
				res += dist(L[it].first, L[it].second, L[who].first, L[who].second);
			return res;
		}
		int mid = (lo + hi) / 2;
		return query(2 * x, lo, mid, from, to, who) + query(2 * x + 1, mid, hi, from, to, who);
	}
};

tournament T;

void scale(ld &x, ld &y) {
	x /= 1000;
	y /= 1000;
}

void load() {
	scanf("%d%Lf%Lf%d", &N, &P, &Q, &M);
	scale(P, Q);
	for (int i = 0; i < N; i++) {
		ld a, b;
		scanf("%Lf%Lf", &a, &b);
		scale(a, b);
		L[i] = {a, a * P + b - Q};
	}
}

void intersect(ld a, ld b, ld r, int who) {
	ld A = a * a + 1;
	ld B = 2 * a * b;
	ld C = b * b - r * r;
	ld D = B * B - 4 * A * C;
	if (D < 0)
		return;
	ld x1 = (-B + sqrt(D)) / (2 * A);
	ld x2 = (-B - sqrt(D)) / (2 * A);
	ld alpha1 = atan2(a * x1 + b, x1);
	ld alpha2 = atan2(a * x2 + b, x2);
	if (alpha1 > alpha2)
		swap(alpha1, alpha2);
	v.push_back({alpha1, alpha2, who});
	all.push_back(alpha1);
	all.push_back(alpha2);
}

void compress(ld &ref) {
	ref = lower_bound(all.begin(), all.end(), ref) - all.begin();
}

ld calc(ld r, bool sum = false) {
	T.init();
	all.clear();
	v.clear();
	for (int i = 0; i < N; i++)
		intersect(L[i].first, L[i].second, r, i);

	sort(all.begin(), all.end());

	for (auto &it : v) {
		compress(it.l);
		compress(it.r);
	}

	sort(v.begin(), v.end());

	ld res = 0;
	for (auto it : v) {
		res += T.query(1, 0, offset, it.l, it.r + 1, sum ? it.id : -1);
		T.update(it.r, sum ? it.id : -1);
	}

	return res;
}

ld solve() {
	ld lo1 = 0, hi1 = 4e9;
	ld lo2 = 0, hi2 = 4e9;
	for (int it = 0; it < 75; it++) {
		ld mid1 = (lo1 + hi1) / 2;
		ld mid2 = (lo2 + hi2) / 2;
		if (calc(mid1) < M)
			lo1 = mid1;
		else
			hi1 = mid1;
		if (calc(mid2) >= M)
			hi2 = mid2;
		else
			lo2 = mid2;
	}

	return calc(lo1, true) + (M - calc(lo1)) * lo2;
}

int main() {
	load();
	printf("%.10Lf\n", solve());
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct point {
	double x, y;
	point(double a=0, double b=0):x(a), y(b){}
};
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, double k) {
	return point(a.x*k, a.y*k);
}
point operator/(point a, double k) {
	return point(a.x/k, a.y/k);
}
double dis(point x) {
	return sqrt(x.x*x.x+x.y*x.y);
}
double cross(point a, point b) {
	return a.x*b.y-a.y*b.x;
}
bool operator<(point a, point b) {
	if (fabs(b.y) < 1e-10 && b.x < 0) return 0;
	if (fabs(a.y) < 1e-10 && a.x < 0) return 1;
	if (a.y * b.y < 0) return a.y < b.y;
	return cross(a, b) > 0;
}
bool operator==(point a, point b) {
	return fabs(dis(a-b)) < 1e-10;
}
point cut(point a, point b, double k) {
	return point(a.x*(1-k)+b.x*k, a.y*(1-k)+b.y*k);
}
struct line {
	point a, dir;
	line(point x=point(), point y=point()):a(x), dir(y){}
}l[50001];
double dis(line l, point a) {
	return cross(l.dir, a-l.a)/dis(l.dir);
}
point intersect(line l1, line l2) {
	double d1 = dis(l1, l2.a), d2 = dis(l1, l2.a+l2.dir);
	return cut(l2.a, l2.a+l2.dir, d1/(d1-d2));
}
int n;
struct info {
	point p1, p2;
}i0[50001];
point a0[100001];
bool operator<(const info &a, const info &b) {
	if (a.p1 == b.p1) return a.p2 < b.p2;
	return a.p1 < b.p1;
}
double st[50001];
int c[100001];
void modify(int x) {
	for (; x <= n * 2; x += x & -x) ++c[x];
}
int query(int x) {
	int ans = 0;
	for (; x; x -= x & -x) ans += c[x];
	return ans;
}
int cnt, tot;
long long check(double d) {
	cnt = 0, tot = 0;
	for (int i = 1; i <= n; i++)
		if (dis(l[i], point(0,0)) <= d) {
			point p = intersect(l[i], line(point(0,0), point(-l[i].dir.y, l[i].dir.x)));
			if (dis(p) > d) break;
			double d0 = sqrt(d*d-dis(p)*dis(p));
			point tmp = l[i].dir/dis(l[i].dir)*d0;
			point p1 = p+tmp, p2 = p-tmp;
			if (p2 < p1) swap(p1, p2);
			++cnt, i0[cnt].p1 = p1, i0[cnt].p2 = p2;
			a0[++tot] = p1, a0[++tot] = p2;
		}
	sort(i0 + 1, i0 + cnt + 1);
	sort(a0 + 1, a0 + tot + 1);
	tot = unique(a0 + 1, a0 + tot + 1) - a0 - 1;
	long long ans = 0;
	memset(c, 0, sizeof(c));
	for (int i = 1; i <= cnt; i++) {
		int n1 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p1) - a0;
		int n2 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p2) - a0;
		ans += query(n2) - query(n1-1);
		modify(n2);
	}
	return ans;
}
int main() {
	cin >> n;
	double x, y;
	int m;
	cin >> x >> y >> m;
	x /= 1000, y /= 1000;
	for (int i = 1; i <= n; i++) {
		double a, b;
		cin >> a >> b;
		a /= 1000, b /= 1000;
		b += a*x-y;
		l[i] = line(point(0, b), point(1, a));
	}
	double l = 0, r = 1e12;
	for (int i = 0; i <= 100; i++) {
		double mid = (l + r) / 2;
		if (check(mid) < m) l = mid;
		else r = mid;
	}
	check(l);
	set<pair<point, point> > s0;
	double ans = 0;
	for (int i = 1; i <= cnt; i++) {
		while (s0.size() && s0.begin()->first < i0[i].p1) s0.erase(s0.begin());
		for (auto j : s0) {
			if (i0[i].p2 < j.first) break;
			--m;
			point p1 = i0[i].p1, p2 = i0[i].p2;
			point p3 = j.second, p4 = j.first;
			if (p1 == p2) ans += dis(p1);
			else if (p3 == p4) ans += dis(p3);
			else {
				point p0 =intersect(line(p1,p2-p1), line(p3,p4-p3));
				ans += dis(p0);
			}
		}
		s0.insert(make_pair(i0[i].p2, i0[i].p1));
	}
	ans += l*m;
	cout << fixed << setprecision(9) << ans << endl;
}


#include<bits/stdc++.h>
using namespace std;
struct point {
	double x, y;
	point(double a=0, double b=0):x(a), y(b){}
};
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, double k) {
	return point(a.x*k, a.y*k);
}
point operator/(point a, double k) {
	return point(a.x/k, a.y/k);
}
double dis(point x) {
	return sqrt(x.x*x.x+x.y*x.y);
}
double cross(point a, point b) {
	return a.x*b.y-a.y*b.x;
}
bool operator<(point a, point b) {
	if (fabs(b.y) < 1e-10 && b.x < 0) return 0;
	if (fabs(a.y) < 1e-10 && a.x < 0) return 1;
	if (a.y * b.y < 0) return a.y < b.y;
	return cross(a, b) > 0;
}
bool operator==(point a, point b) {
	return fabs(dis(a-b)) < 1e-10;
}
point cut(point a, point b, double k) {
	return point(a.x*(1-k)+b.x*k, a.y*(1-k)+b.y*k);
}
struct line {
	point a, dir;
	line(point x=point(), point y=point()):a(x), dir(y){}
}l[50001];
double dis(line l, point a) {
	return cross(l.dir, a-l.a)/dis(l.dir);
}
point intersect(line l1, line l2) {
	double d1 = dis(l1, l2.a), d2 = dis(l1, l2.a+l2.dir);
	return cut(l2.a, l2.a+l2.dir, d1/(d1-d2));
}
int n;
struct info {
	point p1, p2;
}i0[50001];
point a0[100001];
bool operator<(const info &a, const info &b) {
	if (a.p1 == b.p1) return a.p2 < b.p2;
	return a.p1 < b.p1;
}
double st[50001];
int c[100001];
void modify(int x) {
	for (; x <= n * 2; x += x & -x) ++c[x];
}
int query(int x) {
	int ans = 0;
	for (; x; x -= x & -x) ans += c[x];
	return ans;
}
int cnt, tot;
long long check(double d) {
	cnt = 0, tot = 0;
	for (int i = 1; i <= n; i++)
		if (fabs(dis(l[i], point(0,0))) <= d) {
			point p = intersect(l[i], line(point(0,0), point(-l[i].dir.y, l[i].dir.x)));
			if (dis(p) > d) break;
			double d0 = sqrt(d*d-dis(p)*dis(p));
			point tmp = l[i].dir/dis(l[i].dir)*d0;
			point p1 = p+tmp, p2 = p-tmp;
			if (p2 < p1) swap(p1, p2);
			++cnt, i0[cnt].p1 = p1, i0[cnt].p2 = p2;
			a0[++tot] = p1, a0[++tot] = p2;
		}
	sort(i0 + 1, i0 + cnt + 1);
	sort(a0 + 1, a0 + tot + 1);
	tot = unique(a0 + 1, a0 + tot + 1) - a0 - 1;
	long long ans = 0;
	memset(c, 0, sizeof(c));
	for (int i = 1; i <= cnt; i++) {
		int n1 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p1) - a0;
		int n2 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p2) - a0;
		ans += query(n2) - query(n1-1);
		modify(n2);
	}
	return ans;
}
int main() {
	cin >> n;
	double x, y;
	int m;
	cin >> x >> y >> m;
	x /= 1000, y /= 1000;
	for (int i = 1; i <= n; i++) {
		double a, b;
		cin >> a >> b;
		a /= 1000, b /= 1000;
		b += a*x-y;
		l[i] = line(point(0, b), point(1, a));
	}
	double l = 0, r = 1e12;
	for (int i = 0; i <= 100; i++) {
		double mid = (l + r) / 2;
		if (check(mid) < m) l = mid;
		else r = mid;
	}
	check(l);
	set<pair<point, point> > s0;
	double ans = 0;
	for (int i = 1; i <= cnt; i++) {
		while (s0.size() && s0.begin()->first < i0[i].p1) s0.erase(s0.begin());
		for (auto j : s0) {
			if (i0[i].p2 < j.first) break;
			--m;
			point p1 = i0[i].p1, p2 = i0[i].p2;
			point p3 = j.second, p4 = j.first;
			if (p1 == p2) ans += dis(p1);
			else if (p3 == p4) ans += dis(p3);
			else {
				point p0 =intersect(line(p1,p2-p1), line(p3,p4-p3));
				ans += dis(p0);
			}
		}
		s0.insert(make_pair(i0[i].p2, i0[i].p1));
	}
	ans += l*m;
	cout << fixed << setprecision(9) << ans << endl;
}


#include<bits/stdc++.h>
using namespace std;
struct point {
	double x, y;
	point(double a=0, double b=0):x(a), y(b){}
};
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, double k) {
	return point(a.x*k, a.y*k);
}
point operator/(point a, double k) {
	return point(a.x/k, a.y/k);
}
double dis(point x) {
	return sqrt(x.x*x.x+x.y*x.y);
}
double cross(point a, point b) {
	return a.x*b.y-a.y*b.x;
}
bool operator<(point a, point b) {
	if (a.y * b.y < 0) return a.y < b.y;
	return cross(a, b) > 0;
}
bool operator==(point a, point b) {
	return fabs(dis(a-b)) < 1e-10;
}
point cut(point a, point b, double k) {
	return point(a.x*(1-k)+b.x*k, a.y*(1-k)+b.y*k);
}
struct line {
	point a, dir;
	line(point x=point(), point y=point()):a(x), dir(y){}
}l[50001];
double dis(line l, point a) {
	return cross(l.dir, a-l.a)/dis(l.dir);
}
point intersect(line l1, line l2) {
	double d1 = dis(l1, l2.a), d2 = dis(l1, l2.a+l2.dir);
	return cut(l2.a, l2.a+l2.dir, d1/(d1-d2));
}
int n;
struct info {
	point p1, p2;
}i0[50001];
point a0[100001];
bool operator<(const info &a, const info &b) {
	if (a.p1 == b.p1) return a.p2 < b.p2;
	return a.p1 < b.p1;
}
double st[50001];
int c[100001];
void modify(int x) {
	for (; x <= n * 2; x += x & -x) ++c[x];
}
int query(int x) {
	int ans = 0;
	for (; x; x -= x & -x) ans += c[x];
	return ans;
}
int cnt, tot;
long long check(double d) {
	cnt = 0, tot = 0;
	for (int i = 1; i <= n; i++)
		if (dis(l[i], point(0,0)) <= d) {
			point p = intersect(l[i], line(point(0,0), point(-l[i].dir.y, l[i].dir.x)));
			double d0 = sqrt(d*d-dis(p)*dis(p));
			point tmp = l[i].dir/dis(l[i].dir)*d0;
			point p1 = p+tmp, p2 = p-tmp;
			if (p2 < p1) swap(p1, p2);
			++cnt, i0[cnt].p1 = p1, i0[cnt].p2 = p2;
			a0[++tot] = p1, a0[++tot] = p2;
		}
	sort(i0 + 1, i0 + cnt + 1);
	sort(a0 + 1, a0 + tot + 1);
	tot = unique(a0 + 1, a0 + tot + 1) - a0 - 1;
	long long ans = 0;
	memset(c, 0, sizeof(c));
	for (int i = 1; i <= cnt; i++) {
		int n1 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p1) - a0;
		int n2 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p2) - a0;
		ans += query(n2) - query(n1-1);
		modify(n2);
	}
	return ans;
}
int main() {
	cin >> n;
	double x, y;
	int m;
	cin >> x >> y >> m;
	x /= 1000, y /= 1000;
	for (int i = 1; i <= n; i++) {
		double a, b;
		cin >> a >> b;
		a /= 1000, b /= 1000;
		b += a*x-y;
		l[i] = line(point(0, b), point(1, a));
	}
	double l = 0, r = 1e12;
	for (int i = 0; i <= 100; i++) {
		double mid = (l + r) / 2;
		if (check(mid) < m) l = mid;
		else r = mid;
	}
	set<pair<point, point> > s0;
	double ans = 0;
	for (int i = 1; i <= cnt; i++) {
		while (s0.size() && s0.begin()->first < i0[i].p1) s0.erase(s0.begin());
		for (auto j : s0) {
			if (i0[i].p2 < j.first) break;
			point p1 = i0[i].p1, p2 = i0[i].p2;
			point p3 = j.second, p4 = j.first;
			--m, ans += dis(intersect(line(p1,p2-p1), line(p3,p4-p3)));
		}
		s0.insert(make_pair(i0[i].p2, i0[i].p1));
	}
	ans += l*m;
	cout << fixed << setprecision(9) << ans << endl;
}


#include<bits/stdc++.h>
using namespace std;
struct point {
	double x, y;
	point(double a=0, double b=0):x(a), y(b){}
};
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, double k) {
	return point(a.x*k, a.y*k);
}
point operator/(point a, double k) {
	return point(a.x/k, a.y/k);
}
double dis(point x) {
	return sqrt(x.x*x.x+x.y*x.y);
}
double cross(point a, point b) {
	return a.x*b.y-a.y*b.x;
}
bool operator<(point a, point b) {
	if (a.y * b.y < 0) return a.y < b.y;
	return cross(a, b) > 0;
}
bool operator==(point a, point b) {
	return fabs(dis(a-b)) < 1e-10;
}
point cut(point a, point b, double k) {
	return point(a.x*(1-k)+b.x*k, a.y*(1-k)+b.y*k);
}
struct line {
	point a, dir;
	line(point x=point(), point y=point()):a(x), dir(y){}
}l[50001];
double dis(line l, point a) {
	return cross(l.dir, a-l.a)/dis(l.dir);
}
point intersect(line l1, line l2) {
	double d1 = dis(l1, l2.a), d2 = dis(l1, l2.a+l2.dir);
	return cut(l2.a, l2.a+l2.dir, d1/(d1-d2));
}
int n;
struct info {
	point p1, p2;
}i0[50001];
point a0[100001];
bool operator<(const info &a, const info &b) {
	if (a.p1 == b.p1) return a.p2 < b.p2;
	return a.p1 < b.p1;
}
double st[50001];
int c[100001];
void modify(int x) {
	for (; x <= n * 2; x += x & -x) ++c[x];
}
int query(int x) {
	int ans = 0;
	for (; x; x -= x & -x) ans += c[x];
	return ans;
}
int cnt, tot;
long long check(double d) {
	cnt = 0, tot = 0;
	for (int i = 1; i <= n; i++)
		if (dis(l[i], point(0,0)) <= d) {
			point p = intersect(l[i], line(point(0,0), point(-l[i].dir.y, l[i].dir.x)));
			if (dis(p) > d) break;
			double d0 = sqrt(d*d-dis(p)*dis(p));
			point tmp = l[i].dir/dis(l[i].dir)*d0;
			point p1 = p+tmp, p2 = p-tmp;
			if (p2 < p1) swap(p1, p2);
			++cnt, i0[cnt].p1 = p1, i0[cnt].p2 = p2;
			a0[++tot] = p1, a0[++tot] = p2;
		}
	sort(i0 + 1, i0 + cnt + 1);
	sort(a0 + 1, a0 + tot + 1);
	tot = unique(a0 + 1, a0 + tot + 1) - a0 - 1;
	long long ans = 0;
	memset(c, 0, sizeof(c));
	for (int i = 1; i <= cnt; i++) {
		int n1 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p1) - a0;
		int n2 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p2) - a0;
		ans += query(n2) - query(n1-1);
		modify(n2);
	}
	return ans;
}
int main() {
	cin >> n;
	double x, y;
	int m;
	cin >> x >> y >> m;
	x /= 1000, y /= 1000;
	for (int i = 1; i <= n; i++) {
		double a, b;
		cin >> a >> b;
		a /= 1000, b /= 1000;
		b += a*x-y;
		l[i] = line(point(0, b), point(1, a));
	}
	double l = 0, r = 1e12;
	for (int i = 0; i <= 100; i++) {
		double mid = (l + r) / 2;
		if (check(mid) < m) l = mid;
		else r = mid;
	}
	set<pair<point, point> > s0;
	double ans = 0;
	for (int i = 1; i <= cnt; i++) {
		while (s0.size() && s0.begin()->first < i0[i].p1) s0.erase(s0.begin());
		for (auto j : s0) {
			if (i0[i].p2 < j.first) break;
			--m;
			point p1 = i0[i].p1, p2 = i0[i].p2;
			point p3 = j.second, p4 = j.first;
			if (p1 == p2) ans += dis(p1);
			else if (p3 == p4) ans += dis(p3);
			else ans += dis(intersect(line(p1,p2-p1), line(p3,p4-p3)));
		}
		s0.insert(make_pair(i0[i].p2, i0[i].p1));
	}
	ans += l*m;
	cout << fixed << setprecision(9) << ans << endl;
}


#include<bits/stdc++.h>
using namespace std;
struct point {
	double x, y;
	point(double a=0, double b=0):x(a), y(b){}
};
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, double k) {
	return point(a.x*k, a.y*k);
}
point operator/(point a, double k) {
	return point(a.x/k, a.y/k);
}
double dis(point x) {
	return sqrt(x.x*x.x+x.y*x.y);
}
double cross(point a, point b) {
	return a.x*b.y-a.y*b.x;
}
bool operator<(point a, point b) {
	if (a.y * b.y < 0) return a.y < b.y;
	return cross(a, b) > 0;
}
bool operator==(point a, point b) {
	return fabs(dis(a-b)) < 1e-10;
}
point cut(point a, point b, double k) {
	return point(a.x*(1-k)+b.x*k, a.y*(1-k)+b.y*k);
}
struct line {
	point a, dir;
	line(point x=point(), point y=point()):a(x), dir(y){}
}l[50001];
double dis(line l, point a) {
	return cross(l.dir, a-l.a)/dis(l.dir);
}
point intersect(line l1, line l2) {
	double d1 = dis(l1, l2.a), d2 = dis(l1, l2.a+l2.dir);
	return cut(l2.a, l2.a+l2.dir, d1/(d1-d2));
}
int n;
struct info {
	point p1, p2;
}i0[50001];
point a0[100001];
bool operator<(const info &a, const info &b) {
	if (a.p1 == b.p1) return a.p2 < b.p2;
	return a.p1 < b.p1;
}
double st[50001];
int c[100001];
void modify(int x) {
	for (; x <= n * 2; x += x & -x) ++c[x];
}
int query(int x) {
	int ans = 0;
	for (; x; x -= x & -x) ans += c[x];
	return ans;
}
int cnt, tot;
long long check(double d) {
	cnt = 0, tot = 0;
	for (int i = 1; i <= n; i++)
		if (dis(l[i], point(0,0)) <= d) {
			point p = intersect(l[i], line(point(0,0), point(-l[i].dir.y, l[i].dir.x)));
			if (dis(p) > d) break;
			double d0 = sqrt(d*d-dis(p)*dis(p));
			point tmp = l[i].dir/dis(l[i].dir)*d0;
			point p1 = p+tmp, p2 = p-tmp;
			if (p2 < p1) swap(p1, p2);
			++cnt, i0[cnt].p1 = p1, i0[cnt].p2 = p2;
			a0[++tot] = p1, a0[++tot] = p2;
		}
	sort(i0 + 1, i0 + cnt + 1);
	sort(a0 + 1, a0 + tot + 1);
	tot = unique(a0 + 1, a0 + tot + 1) - a0 - 1;
	long long ans = 0;
	memset(c, 0, sizeof(c));
	for (int i = 1; i <= cnt; i++) {
		int n1 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p1) - a0;
		int n2 = lower_bound(a0 + 1, a0 + tot + 1, i0[i].p2) - a0;
		ans += query(n2) - query(n1-1);
		modify(n2);
	}
	return ans;
}
int main() {
	cin >> n;
	double x, y;
	int m;
	cin >> x >> y >> m;
	x /= 1000, y /= 1000;
	for (int i = 1; i <= n; i++) {
		double a, b;
		cin >> a >> b;
		a /= 1000, b /= 1000;
		b += a*x-y;
		l[i] = line(point(0, b), point(1, a));
	}
	double l = 0, r = 1e12;
	for (int i = 0; i <= 100; i++) {
		double mid = (l + r) / 2;
		if (check(mid) < m) l = mid;
		else r = mid;
	}
	set<pair<point, point> > s0;
	double ans = 0;
	for (int i = 1; i <= cnt; i++) {
		while (s0.size() && s0.begin()->first < i0[i].p1) s0.erase(s0.begin());
		for (auto j : s0) {
			if (i0[i].p2 < j.first) break;
			--m;
			point p1 = i0[i].p1, p2 = i0[i].p2;
			point p3 = j.second, p4 = j.first;
			if (p1 == p2 && p3 == p4) assert(fabs(dis(p1)-dis(p3)) < 1e-10);
			if (p1 == p2) ans += dis(p1);
			else if (p3 == p4) ans += dis(p3);
			else ans += dis(intersect(line(p1,p2-p1), line(p3,p4-p3)));
		}
		s0.insert(make_pair(i0[i].p2, i0[i].p1));
	}
	ans += l*m;
	cout << fixed << setprecision(9) << ans << endl;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long double dou;
const int N=200200;
const dou EPS=1e-6,pi=acos(-1.0);
int n,m,T,Q,cnt;
int c[N],f[N],id[N];
dou X,Y,sum,ans,L,R,g[N];
struct lin{dou k,b;}p[N];
struct itv{
	dou l,r;
	bool operator < (const itv&a)const{return l<a.l;}
}q[N];
struct Itv{int l,r;}q1[N];
dou f2(dou x){return x*x;}
dou cro(lin u,lin v){
	dou t=v.k-u.k;
	dou x=(u.b-v.b)/t,y=(u.b*v.k-v.b*u.k)/t;
	return sqrt(f2(x)+f2(y));
}
void add(int x,int y){ for(;x<=T;x+=x&-x) c[x]+=y;}
int ask(int x){int y=0;for(;x;x-=x&-x) y+=c[x]; return y;}
int chk(dou r,int o){
	sum=cnt=Q=T=0;
	FOR(i,1,n){
		dou k=p[i].k,b=p[i].b;
		dou A=f2(k)+1,d=abs(b)/sqrt(A);
		if(r<d+EPS) continue;
		dou B=2*k*b,C=f2(b)-f2(r);
		d=sqrt(B*B-4*A*C);
		dou x1=(-B+d)/2/A,x2=(-B-d)/2/A;
		dou l=atan2(k*x1+b,x1),r=atan2(k*x2+b,x2);
		if(l>r) swap(l,r);g[++T]=l;g[++T]=r;
		q[++Q]={l,r};f[Q]=i;
	}
	sort(g+1,g+T+1);
	FOR(i,1,T) c[i]=0;
	FOR(i,1,Q){
		q1[i].l=upper_bound(g+1,g+T+1,q[i].l)-g-1;
		q1[i].r=upper_bound(g+1,g+T+1,q[i].r)-g-1;
		id[q1[i].l]=id[q1[i].r]=i;
		//cout<<q1[i].l<<" "<<q1[i].r<<"\n";
	}
	FOR(i,1,T)if(q1[id[i]].l==i){
		int v=id[i];
		cnt+=ask(q1[v].r)-ask(q1[v].l),add(q1[v].r,1);
		if(o) FOR(j,q1[v].l+1,q1[v].r-1)
			if(q1[id[j]].r==j && q1[id[j]].l<q1[v].l)
				sum+=cro(p[f[v]],p[f[id[j]]]);
	}
	return cnt;
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%Lf%Lf%d",&n,&X,&Y,&m);
	X/=1000;Y/=1000;
	FOR(i,1,n){
		scanf("%Lf%Lf",&p[i].k,&p[i].b);
		p[i].k/=1000,p[i].b/=1000;
		p[i].b+=p[i].k*X-Y;
	}
	L=0;R=1e10;
	while(L+EPS<R){
		dou md=(L+R)/2;
		chk(md,0)>m?R=md:L=md;
	}
	chk(L-1e-6,1);
	//chk(7.2,1);cout<<cnt<<' '<<sum<<'\n';
	ans=sum+R*(m-cnt);
	printf("%.9Lf",ans);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long double dou;
const int N=200200;
const dou EPS=1e-9,pi=acos(-1.0);
int n,m,T,Q,cnt;
int c[N],f[N],id[N];
dou X,Y,sum,ans,L,R,g[N];
struct lin{dou k,b;}p[N];
struct itv{
	dou l,r;
	bool operator < (const itv&a)const{return l<a.l;}
}q[N];
struct Itv{int l,r;}q1[N];
dou f2(dou x){return x*x;}
dou cro(lin u,lin v){
	dou t=v.k-u.k;
	dou x=(u.b-v.b)/t,y=(u.b*v.k-v.b*u.k)/t;
	return sqrt(f2(x)+f2(y));
}
void add(int x,int y){ for(;x<=T;x+=x&-x) c[x]+=y;}
int ask(int x){int y=0;for(;x;x-=x&-x) y+=c[x]; return y;}
int chk(dou r,int o){
	sum=cnt=Q=T=0;
	FOR(i,1,n){
		dou k=p[i].k,b=p[i].b;
		dou A=f2(k)+1,d=abs(b)/sqrt(A);
		if(r<d+EPS) continue;
		dou B=2*k*b,C=f2(b)-f2(r);
		d=sqrt(B*B-4*A*C);
		dou x1=(-B+d)/2/A,x2=(-B-d)/2/A;
		dou l=atan2(k*x1+b,x1),r=atan2(k*x2+b,x2);
		if(l>r) swap(l,r);g[++T]=l;g[++T]=r;
		q[++Q]={l,r};f[Q]=i;
	}
	sort(g+1,g+T+1);
	FOR(i,1,T) c[i]=0;
	FOR(i,1,Q){
		q1[i].l=upper_bound(g+1,g+T+1,q[i].l)-g-1;
		q1[i].r=upper_bound(g+1,g+T+1,q[i].r)-g-1;
		id[q1[i].l]=id[q1[i].r]=i;
		//cout<<q1[i].l<<" "<<q1[i].r<<"\n";
	}
	FOR(i,1,T)if(q1[id[i]].l==i){
		int v=id[i];
		cnt+=ask(q1[v].r)-ask(q1[v].l),add(q1[v].r,1);
		if(o) FOR(j,q1[v].l+1,q1[v].r-1)
			if(q1[id[j]].r==j && q1[id[j]].l<q1[v].l)
				sum+=cro(p[f[v]],p[f[id[j]]]);
	}
	return cnt;
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%Lf%Lf%d",&n,&X,&Y,&m);
	X/=1000;Y/=1000;
	FOR(i,1,n){
		scanf("%Lf%Lf",&p[i].k,&p[i].b);
		p[i].k/=1000,p[i].b/=1000;
		p[i].b+=p[i].k*X-Y;
	}
	L=0;R=1e10;
	while(L+EPS<R){
		dou md=(L+R)/2;
		chk(md,0)>m?R=md:L=md;
	}
	chk(L,1);
	//chk(7.2,1);cout<<cnt<<' '<<sum<<'\n';
	ans=sum-R*(cnt-m);
	printf("%.9Lf",ans);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long double dou;
const int N=200200;
const dou EPS=1e-13,pi=acos(-1.0);
int n,m,T,Q,cnt;
int c[N],f[N],id[N];
dou X,Y,sum,ans,L,R,g[N];
struct lin{dou k,b;}p[N];
struct itv{
	dou l,r;
	bool operator < (const itv&a)const{return l<a.l;}
}q[N];
struct Itv{int l,r;}q1[N];
dou f2(dou x){return x*x;}
dou cro(lin u,lin v){
	dou t=v.k-u.k;
	dou x=(u.b-v.b)/t,y=(u.b*v.k-v.b*u.k)/t;
	return sqrt(f2(x)+f2(y));
}
void add(int x,int y){ for(;x<=T;x+=x&-x) c[x]+=y;}
int ask(int x){int y=0;for(;x;x-=x&-x) y+=c[x]; return y;}
int chk(dou r,int o){
	sum=cnt=Q=T=0;
	FOR(i,1,n){
		dou k=p[i].k,b=p[i].b;
		dou A=f2(k)+1,d=abs(b)/sqrt(A);
		if(r<d+EPS) continue;
		dou B=2*k*b,C=f2(b)-f2(r);
		d=sqrt(B*B-4*A*C);
		dou x1=(-B+d)/2/A,x2=(-B-d)/2/A;
		dou l=atan2(k*x1+b,x1),r=atan2(k*x2+b,x2);
		if(l>r) swap(l,r);g[++T]=l;g[++T]=r;
		q[++Q]={l,r};f[Q]=i;
	}
	sort(g+1,g+T+1);
	FOR(i,1,T) c[i]=0;
	FOR(i,1,Q){
		q1[i].l=upper_bound(g+1,g+T+1,q[i].l)-g-1;
		q1[i].r=upper_bound(g+1,g+T+1,q[i].r)-g-1;
		id[q1[i].l]=id[q1[i].r]=i;
		//cout<<q1[i].l<<" "<<q1[i].r<<"\n";
	}
	FOR(i,1,T)if(q1[id[i]].l==i){
		int v=id[i];
		cnt+=ask(q1[v].r)-ask(q1[v].l),add(q1[v].r,1);
		if(o) FOR(j,q1[v].l+1,q1[v].r-1)
			if(q1[id[j]].r==j && q1[id[j]].l<q1[v].l)
				sum+=cro(p[f[v]],p[f[id[j]]]);
	}
	return cnt;
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%Lf%Lf%d",&n,&X,&Y,&m);
	X/=1000;Y/=1000;
	FOR(i,1,n){
		scanf("%Lf%Lf",&p[i].k,&p[i].b);
		p[i].k/=1000,p[i].b/=1000;
		p[i].b+=p[i].k*X-Y;
	}
	L=0;R=1e10;
	while(L+EPS<R){
		dou md=(L+R)/2;
		chk(md,0)>m?R=md:L=md;
	}
	chk(L,1);
	//chk(7.2,1);cout<<cnt<<' '<<sum<<'\n';
	ans=sum-R*(cnt-m);
	printf("%.9Lf",ans);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long double dou;
const int N=200200;
const dou EPS=1e-9,pi=acos(-1.0);
int n,m,T,Q,cnt;
int c[N],f[N],id[N];
dou X,Y,sum,ans,L,R,g[N];
struct lin{dou k,b;}p[N];
struct itv{
	dou l,r;
	bool operator < (const itv&a)const{return l<a.l;}
}q[N];
struct Itv{int l,r;}q1[N];
dou f2(dou x){return x*x;}
dou cro(lin u,lin v){
	dou t=v.k-u.k;
	dou x=(u.b-v.b)/t,y=u.k*x+u.b;
	return sqrt(f2(x)+f2(y));
}
void add(int x,int y){ for(;x<=T;x+=x&-x) c[x]+=y;}
int ask(int x){int y=0;for(;x;x-=x&-x) y+=c[x]; return y;}
int chk(dou r,int o){
	sum=cnt=Q=T=0;
	FOR(i,1,n){
		dou k=p[i].k,b=p[i].b;
		dou A=f2(k)+1,d=abs(b)/sqrt(A);
		if(r<d+EPS) continue;
		dou B=2*k*b,C=f2(b)-f2(r);
		d=sqrt(B*B-4*A*C);
		dou x1=(-B+d)/2/A,x2=(-B-d)/2/A;
		dou l=atan2(k*x1+b,x1),r=atan2(k*x2+b,x2);
		if(l>r) swap(l,r);g[++T]=l;g[++T]=r;
		q[++Q]={l,r};f[Q]=i;
	}
	sort(g+1,g+T+1);
	FOR(i,1,T) c[i]=0;
	FOR(i,1,Q){
		q1[i].l=upper_bound(g+1,g+T+1,q[i].l)-g-1;
		q1[i].r=upper_bound(g+1,g+T+1,q[i].r)-g-1;
		id[q1[i].l]=id[q1[i].r]=i;
		//cout<<q1[i].l<<" "<<q1[i].r<<"\n";
	}
	FOR(i,1,T)if(q1[id[i]].l==i){
		int v=id[i];
		cnt+=ask(q1[v].r)-ask(q1[v].l),add(q1[v].r,1);
		if(o) FOR(j,q1[v].l+1,q1[v].r-1)
			if(q1[id[j]].r==j && q1[id[j]].l<q1[v].l)
				sum+=cro(p[f[v]],p[f[id[j]]]);
	}
	return cnt;
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%Lf%Lf%d",&n,&X,&Y,&m);
	X/=1000;Y/=1000;
	FOR(i,1,n){
		scanf("%Lf%Lf",&p[i].k,&p[i].b);
		p[i].k/=1000,p[i].b/=1000;
		p[i].b+=p[i].k*X-Y;
	}
	L=0;R=1e10;
	while(L+EPS<R){
		dou md=(L+R)/2;
		chk(md,0)>m?R=md:L=md;
	}
	chk(L+EPS,1);cerr<<R<<'\n';
	//chk(7.2,1);cout<<cnt<<' '<<sum<<'\n';
	ans=sum-R*(cnt-m);
	printf("%.9Lf",ans);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long double dou;
const int N=200200;
const dou EPS=1e-9,pi=acos(-1.0);
int n,m,T,Q,cnt;
int c[N],f[N],id[N];
dou X,Y,sum,ans,L,R,g[N];
struct lin{dou k,b;}p[N];
struct itv{
	dou l,r;
	bool operator < (const itv&a)const{return l<a.l;}
}q[N];
struct Itv{int l,r;}q1[N];
dou f2(dou x){return x*x;}
dou cro(lin u,lin v){
	dou t=v.k-u.k;
	dou x=(u.b-v.b)/t,y=(u.b*v.k-v.b*u.k)/t;
	return sqrt(f2(x)+f2(y));
}
void add(int x,int y){ for(;x<=T;x+=x&-x) c[x]+=y;}
int ask(int x){int y=0;for(;x;x-=x&-x) y+=c[x]; return y;}
int chk(dou r,int o){
	sum=cnt=Q=T=0;
	FOR(i,1,n){
		dou k=p[i].k,b=p[i].b;
		dou A=f2(k)+1,d=abs(b)/sqrt(A);
		if(r<d+EPS) continue;
		dou B=2*k*b,C=f2(b)-f2(r);
		d=sqrt(B*B-4*A*C);
		dou x1=(-B+d)/2/A,x2=(-B-d)/2/A;
		dou l=atan2(k*x1+b,x1),r=atan2(k*x2+b,x2);
		if(l>r) swap(l,r);g[++T]=l;g[++T]=r;
		q[++Q]={l,r};f[Q]=i;
	}
	sort(g+1,g+T+1);
	FOR(i,1,T) c[i]=0;
	FOR(i,1,Q){
		q1[i].l=upper_bound(g+1,g+T+1,q[i].l)-g-1;
		q1[i].r=upper_bound(g+1,g+T+1,q[i].r)-g-1;
		id[q1[i].l]=id[q1[i].r]=i;
		//cout<<q1[i].l<<" "<<q1[i].r<<"\n";
	}
	FOR(i,1,T)if(q1[id[i]].l==i){
		int v=id[i];
		cnt+=ask(q1[v].r)-ask(q1[v].l),add(q1[v].r,1);
		if(o) FOR(j,q1[v].l+1,q1[v].r-1)
			if(q1[id[j]].r==j && q1[id[j]].l<q1[v].l)
				sum+=cro(p[f[v]],p[f[id[j]]]);
	}
	return cnt;
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%Lf%Lf%d",&n,&X,&Y,&m);
	X/=1000;Y/=1000;
	FOR(i,1,n){
		scanf("%Lf%Lf",&p[i].k,&p[i].b);
		p[i].k/=1000,p[i].b/=1000;
		p[i].b+=p[i].k*X-Y;
	}
	L=0;R=1e10;
	while(L+EPS<R){
		dou md=(L+R)/2;
		chk(md,0)>m?R=md:L=md;
	}
	chk(max((dou)0,L-1e-6),1);
	//chk(7.2,1);cout<<cnt<<' '<<sum<<'\n';
	ans=sum+(L<EPS?0:L)*(m-cnt);
	printf("%.9Lf",ans);
}


#include<bits/stdc++.h>
#define double long double
typedef long long ll;
ll gi(){
	ll x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch))f^=ch=='-',ch=getchar();
	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
	return f?x:-x;
}
struct vector{double x,y;}O;
vector operator+(vector a,vector b){return{a.x+b.x,a.y+b.y};}
vector operator-(vector a,vector b){return{a.x-b.x,a.y-b.y};}
vector operator*(vector a,double b){return{a.x*b,a.y*b};}
double operator^(vector a,vector b){return a.x*b.y-a.y*b.x;}
double sqr(double x){return x*x;}
double len(vector x){return sqr(x.x)+sqr(x.y);}
double lk[50010],lb[50010],dist[50010],ang[50010];
struct fuck{double p;int i;bool s;}st[100010];
int N,n,m,pl[50010],pr[50010],rpl[50010];
int t[100010];
void update(int x,int o){while(x<=n)t[x]+=o,x+=x&-x;};
int query(int x){int r=0;while(x)r+=t[x],x-=x&-x;return r;}
bool cxk(double mid,bool out=0){
	N=0;
	for(int i=1;i<=n;++i)
		if(dist[i]<mid){
			double s=acosl(dist[i]/mid),p1=ang[i]-s,p2=ang[i]+s;
			if(p1>p2)std::swap(p1,p2);
			st[++N]={p1,i,0};
			st[++N]={p2,i,1};
		}
	std::sort(st+1,st+N+1,[](fuck a,fuck b){return a.p<b.p;});
	memset(t,0,sizeof t);memset(pr,0,sizeof pr);
	for(int i=N,p=n;i;--i)
		if(pr[st[i].i])pl[st[i].i]=p--;
		else pr[st[i].i]=i;
	if(out)return 0;
	ll cnt=0;
	for(int i=N,c=0;i;--i)
		if(pr[st[i].i]==i){
			cnt+=c-query(pl[st[i].i]);
			++c,update(pl[st[i].i],1);
		}else --c,update(pl[st[i].i],-1);
	return cnt>=m;
}
vector cross(int x,int y){
	vector sx={0,lb[x]},a={1,lk[x]},sy={0,lb[y]},b={1,lk[y]};
	vector c=sy-sx;
	double base=(b^c)/(b^a);
	return sx+a*base;
}
const double pi=acos(-1);
int main(){
#ifdef XZZSB
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	n=gi();
	{double x=gi()*1e-3,y=gi()*1e-3;O={x,y};}
	m=gi();
	for(int i=1;i<=n;++i){
		lk[i]=gi()*1e-3,lb[i]=gi()*1e-3;
		ang[i]=atanl(lk[i]);
		if(lk[i]*O.x+lb[i]>O.y)ang[i]+=0.5*pi;
		else ang[i]-=0.5*pi;
		dist[i]=fabsl(lk[i]*O.x+lb[i]-O.y)/sqrtl(1+lk[i]*lk[i]);
	}
	double l=0,r=1e10,mid;int time=100;
	while(time--){
		mid=(l+r)/2;
		if(cxk(mid))r=mid;
		else l=mid;
	}
	cxk(l-1e-9,1);
	std::set<int>S;
	std::set<int>::iterator it;
	double ans=0;int cnt=0;
	for(int i=1;i<=n;++i)rpl[pl[i]]=i;
	for(int i=N,c=0;i;--i)
		if(pr[st[i].i]==i){
			it=S.lower_bound(pl[st[i].i]);
			while(it!=S.end())ans+=sqrtl(len(O-cross(st[i].i,rpl[*it]))),++it,++cnt;
			++c,S.insert(pl[st[i].i]);
		}else --c,S.erase(pl[st[i].i]);
	printf("%.10Lf\n",ans+l*(m-cnt));
	return 0;
}


#include<bits/stdc++.h>
#define double long double
typedef long long ll;
ll gi(){
	ll x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch))f^=ch=='-',ch=getchar();
	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
	return f?x:-x;
}
struct vector{double x,y;}O;
vector operator+(vector a,vector b){return{a.x+b.x,a.y+b.y};}
vector operator-(vector a,vector b){return{a.x-b.x,a.y-b.y};}
vector operator*(vector a,double b){return{a.x*b,a.y*b};}
double operator^(vector a,vector b){return a.x*b.y-a.y*b.x;}
double sqr(double x){return x*x;}
double len(vector x){return sqr(x.x)+sqr(x.y);}
double lk[50010],lb[50010],dist[50010],ang[50010];
struct fuck{double p;int i;bool s;}st[100010];
int N,n,m,pl[50010],pr[50010],rpl[50010];
int t[50010];
void update(int x,int o){while(x<=n)t[x]+=o,x+=x&-x;};
int query(int x){int r=0;while(x)r+=t[x],x-=x&-x;return r;}
const double pi=acos(-1);
bool chk(double mid,bool out=0){
	N=0;
	for(int i=1;i<=n;++i)
		if(dist[i]<mid){
			double s=acosl(dist[i]/mid),p1=ang[i]-s,p2=ang[i]+s;
			if(p1<-pi)p1+=2*pi;if(p2>pi)p2-=2*pi;
			if(p1>p2)std::swap(p1,p2);
			st[++N]={p1,i,0};
			st[++N]={p2,i,1};
		}
	std::sort(st+1,st+N+1,[](fuck a,fuck b){return a.p<b.p;});
	memset(t,0,sizeof t);memset(pr,0,sizeof pr);
	for(int i=N,p=n;i;--i)
		if(pr[st[i].i])pl[st[i].i]=p--;
		else pr[st[i].i]=i;
	if(out)return 0;
	ll cnt=0;
	for(int i=N,c=0;i;--i)
		if(pr[st[i].i]==i){
			cnt+=c-query(pl[st[i].i]);
			++c,update(pl[st[i].i],1);
		}else --c,update(pl[st[i].i],-1);
	return cnt>=m;
}
vector cross(int x,int y){
	vector sx={0,lb[x]},a={1,lk[x]},sy={0,lb[y]},b={1,lk[y]};
	vector c=sy-sx;
	double base=(b^c)/(b^a);
	return sx+a*base;
}
int main(){
#ifdef XZZSB
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	n=gi();
	{double x=gi()*1e-3,y=gi()*1e-3;O={x,y};}
	m=gi();
	for(int i=1;i<=n;++i){
		lk[i]=gi()*1e-3,lb[i]=gi()*1e-3;
		ang[i]=atanl(lk[i]);
		if(lk[i]*O.x+lb[i]>O.y)ang[i]+=0.5*pi;
		else ang[i]-=0.5*pi;
		dist[i]=fabsl(lk[i]*O.x+lb[i]-O.y)/sqrtl(1+lk[i]*lk[i]);
	}
	double l=0,r=1e10,mid;int time=100;
	while(time--){
		mid=(l+r)/2;
		if(chk(mid))r=mid;
		else l=mid;
	}
	for(int i=1;i<=n;++i)pl[i]=0;
	chk(l-1e-7,1);
	std::set<int>S;
	std::set<int>::iterator it;
	double ans=0;int cnt=0;
	for(int i=1;i<=n;++i)rpl[pl[i]]=i;
	fprintf(stderr,"1");
	for(int i=N;i;--i)
		if(pr[st[i].i]==i){
			it=S.lower_bound(pl[st[i].i]);
			while(it!=S.end())ans+=sqrtl(len(O-cross(st[i].i,rpl[*it]))),++it,++cnt;
			S.insert(pl[st[i].i]);
		}else S.erase(pl[st[i].i]);
	printf("%.10Lf\n",ans+l*(m-cnt));
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,n) for(int i=(0);i<(n);i++)
#define qwq(x) cerr<<"# "<<#x<<" = "<<x<<endl
#define pr(x) printf("## %s  %.6Lf\n",#x,x)
#define clr(x) memset(x,0,sizeof x)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;

template<class T> inline void read(T &x){
	int f=0;x=0;char ch=getchar();
	for(;!isdigit(ch);ch=getchar())f|=(ch=='-');
	for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
	if(f)x=-x;
}

const ld eps=1e-10;
const ld Pi=acos(-1);
ld mo(ld x,ld y){
	return sqrtl(x*x+y*y);
}
ld fix(ld a){
	return a>Pi?a-2*Pi:(a<-Pi?a+2*Pi:a);
}
int cmp(ld a,ld b){
	return fabsl(a-b)<eps?0:a<b?-1:1;
}

const int N=100005;
ld d[N],k[N],b[N],dir[N],L[N],R[N],X[N],ox,oy,l,r=1e18,ans;
int id[N],n,cnt,aim,acc;

void create(ld r){
	cnt=0;
	rep(i,1,n){
		if(d[i]>r)continue;
		ld delta=acosl(d[i]/r);
		L[i]=fix(dir[i]-delta);
		R[i]=fix(dir[i]+delta);
		if(L[i]>R[i])swap(L[i],R[i]);
		id[++cnt]=i;
	}
}

int a[N],c[N];
#define lb(x) (x&-x)
void upd(int x,int y){
	for(;x<N;x+=lb(x))c[x]+=y;
}
int qry(int x){
	int res=0;
	for(;x;x-=lb(x))res+=c[x];
	return res;
}
int calc(){
	int res=0,t=0; clr(c),clr(a);
	rep(i,1,cnt) X[++t]=L[id[i]],X[++t]=R[id[i]];
	sort(X+1,X+t+1);
	rep(i,1,cnt){
		int A=lower_bound(X+1,X+t+1,L[id[i]])-X;
		int B=lower_bound(X+1,X+t+1,R[id[i]])-X;
		a[A]=B;
	}
	rep(i,1,t)
		if(a[i]){
			res+=qry(a[i])-qry(i);
			if(res>aim)return aim+1;
			upd(a[i],1);
		}
	return res;
}

set<pair<ld,int> > s;
int push(int u,int v){
	ld x=(b[u]-b[v])/(k[v]-k[u]);
	ld d=mo(x-ox,k[u]*x+b[u]-oy);
	return d<r-eps?(ans+=d,acc++,1):0;
}
void solve(){
	sort(id+1,id+cnt+1,[&](int a,int b){
		return L[a]<L[b];
	});
	rep(i,1,cnt){
		auto it=s.lower_bound(mp(L[id[i]],0));
		for(;it!=s.end()&&it->fi<R[id[i]];it++)
			if(!push(id[i],it->se))break;
		s.insert(mp(R[id[i]],id[i]));
	}
}

int main(){
	read(n);
	read(ox),read(oy),read(aim);
	ox/=1000,oy/=1000;
	rep(i,1,n){
		read(k[i]),read(b[i]);
		k[i]/=1000,b[i]/=1000;
		ld A=k[i],B=-1,C=b[i];
		d[i]=fabsl(A*ox+B*oy+C)/mo(A,B);
		dir[i]=atanl(k[i])+(cmp(oy,k[i]*ox+b[i])<0?Pi/2:-Pi/2);
	}
	REP(T,60){
		ld mid=(l+r)*0.5;
		create(mid);
		if(calc()<aim)l=mid;
		else r=mid;
	}
	create(r),solve();
	ans+=(aim-acc)*r;
	printf("%.8lf\n",(double)ans);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,n) for(int i=(0);i<(n);i++)
#define qwq(x) cerr<<"# "<<#x<<" = "<<x<<endl
#define pr(x) printf("## %s  %.6Lf\n",#x,x)
#define clr(x) memset(x,0,sizeof x)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;

template<class T> inline void read(T &x){
	int f=0;x=0;char ch=getchar();
	for(;!isdigit(ch);ch=getchar())f|=(ch=='-');
	for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
	if(f)x=-x;
}

const ld eps=1e-12;
const ld Pi=acos(-1);
ld mo(ld x,ld y){
	return sqrtl(x*x+y*y);
}
ld fix(ld a){
	return a>Pi?a-2*Pi:(a<-Pi?a+2*Pi:a);
}
int cmp(ld a,ld b){
	return fabsl(a-b)<eps?0:a<b?-1:1;
}

const int N=100005;
ld d[N],k[N],b[N],dir[N],L[N],R[N],X[N],ox,oy,l,r=1e10,ans;
int id[N],n,cnt,aim,acc;

void create(ld r){
	cnt=0;
	rep(i,1,n){
		if(d[i]>r)continue;
		ld delta=acosl(d[i]/r);
		L[i]=fix(dir[i]-delta);
		R[i]=fix(dir[i]+delta);
		if(L[i]>R[i])swap(L[i],R[i]);
		id[++cnt]=i;
	}
}

int a[N],c[N];
#define lb(x) (x&-x)
void upd(int x,int y){
	for(;x<N;x+=lb(x))c[x]+=y;
}
int qry(int x){
	int res=0;
	for(;x;x-=lb(x))res+=c[x];
	return res;
}
int calc(){
	int res=0,t=0; clr(c),clr(a);
	rep(i,1,cnt) X[++t]=L[id[i]],X[++t]=R[id[i]];
	sort(X+1,X+t+1);
	rep(i,1,cnt){
		int A=lower_bound(X+1,X+t+1,L[id[i]])-X;
		int B=lower_bound(X+1,X+t+1,R[id[i]])-X;
		a[A]=B;
	}
	rep(i,1,t)
		if(a[i]){
			res+=qry(a[i])-qry(i);
			if(res>aim)return aim+1;
			upd(a[i],1);
		}
	return res;
}

set<pair<ld,int> > s;
int push(int u,int v){
	ld x=(b[u]-b[v])/(k[v]-k[u]);
	ld d=mo(x-ox,k[u]*x+b[u]-oy);
	return d<r-eps?(ans+=d,acc++,1):0;
}
void solve(){
	sort(id+1,id+cnt+1,[&](int a,int b){
		return L[a]<L[b];
	});
	rep(i,1,cnt){
		auto it=s.lower_bound(mp(L[id[i]],0));
		for(;it!=s.end()&&it->fi<R[id[i]];it++)
			if(!push(id[i],it->se))break;
		s.insert(mp(R[id[i]],id[i]));
	}
}

int main(){
	read(n);
	read(ox),read(oy),read(aim);
	ox/=1000,oy/=1000;
	rep(i,1,n){
		read(k[i]),read(b[i]);
		k[i]/=1000,b[i]/=1000;
		ld A=k[i],B=-1,C=b[i];
		d[i]=fabsl(A*ox+B*oy+C)/mo(A,B);
		dir[i]=atanl(k[i])+(cmp(oy,k[i]*ox+b[i])<0?Pi/2:-Pi/2);
	}
	REP(T,60){
		ld mid=(l+r)*0.5;
		create(mid);
		if(calc()<aim)l=mid;
		else r=mid;
	}
	create(r),solve();
	ans+=(aim-acc)*r;
	printf("%.8lf\n",(double)ans);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,n) for(int i=(0);i<(n);i++)
#define qwq(x) cerr<<"# "<<#x<<" = "<<x<<endl
#define pr(x) printf("## %s  %.6Lf\n",#x,x)
#define clr(x) memset(x,0,sizeof x)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long ll;
typedef double ld;

template<class T> inline void read(T &x){
	int f=0;x=0;char ch=getchar();
	for(;!isdigit(ch);ch=getchar())f|=(ch=='-');
	for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
	if(f)x=-x;
}

const ld eps=1e-10;
const ld Pi=acos(-1);
ld mo(ld x,ld y){
	return sqrt(x*x+y*y);
}
ld fix(ld a){
	return a>Pi?a-2*Pi:(a<-Pi?a+2*Pi:a);
}
int cmp(ld a,ld b){
	return fabs(a-b)<eps?0:a<b?-1:1;
}

const int N=100005;
ld d[N],k[N],b[N],dir[N],L[N],R[N],X[N],ox,oy,l,r=1e10,ans;
int id[N],n,cnt,aim,acc;

void create(ld r){
	cnt=0;
	rep(i,1,n){
		if(d[i]>r)continue;
		ld delta=acos(d[i]/r);
		L[i]=fix(dir[i]-delta);
		R[i]=fix(dir[i]+delta);
		if(L[i]>R[i])swap(L[i],R[i]);
		id[++cnt]=i;
	}
}

int a[N],c[N];
#define lb(x) (x&-x)
void upd(int x,int y){
	for(;x<N;x+=lb(x))c[x]+=y;
}
int qry(int x){
	int res=0;
	for(;x;x-=lb(x))res+=c[x];
	return res;
}
int calc(){
	int res=0,t=0; clr(c),clr(a);
	rep(i,1,cnt) X[++t]=L[id[i]],X[++t]=R[id[i]];
	sort(X+1,X+t+1);
	rep(i,1,cnt){
		int A=lower_bound(X+1,X+t+1,L[id[i]])-X;
		int B=lower_bound(X+1,X+t+1,R[id[i]])-X;
		a[A]=B;
	}
	rep(i,1,t)
		if(a[i]){
			res+=qry(a[i])-qry(i);
			if(res>aim)return aim+1;
			upd(a[i],1);
		}
	return res;
}

set<pair<ld,int> > s;
int push(int u,int v){
	ld x=(b[u]-b[v])/(k[v]-k[u]);
	ld d=mo(x-ox,k[u]*x+b[u]-oy);
	return d<r-eps?(ans+=d,acc++,1):0;
}
void solve(){
	sort(id+1,id+cnt+1,[&](int a,int b){
		return L[a]<L[b];
	});
	rep(i,1,cnt){
		auto it=s.lower_bound(mp(L[id[i]],0));
		for(;it!=s.end()&&it->fi<R[id[i]];it++)
			if(!push(id[i],it->se))break;
		s.insert(mp(R[id[i]],id[i]));
	}
}

int main(){
	read(n);
	read(ox),read(oy),read(aim);
	ox/=1000,oy/=1000;
	rep(i,1,n){
		read(k[i]),read(b[i]);
		k[i]/=1000,b[i]/=1000;
		ld A=k[i],B=-1,C=b[i];
		d[i]=fabs(A*ox+B*oy+C)/mo(A,B);
		dir[i]=atan(k[i])+(cmp(oy,k[i]*ox+b[i])<0?Pi/2:-Pi/2);
	}
	REP(T,60){
		ld mid=(l+r)*0.5;
		create(mid);
		if(calc()<aim)l=mid;
		else r=mid;
	}
	r=l,create(r),solve();
	ans+=(aim-acc)*r;
	printf("%.8lf\n",(double)ans);
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,n) for(int i=(0);i<(n);i++)
#define qwq(x) cerr<<"# "<<#x<<" = "<<x<<endl
#define pr(x) printf("## %s  %.6Lf\n",#x,x)
#define clr(x) memset(x,0,sizeof x)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long ll;
typedef long double ld;

template<class T> inline void read(T &x){
	int f=0;x=0;char ch=getchar();
	for(;!isdigit(ch);ch=getchar())f|=(ch=='-');
	for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
	if(f)x=-x;
}

const ld eps=1e-10;
const ld Pi=acos(-1);
ld mo(ld x,ld y){
	return sqrtl(x*x+y*y);
}
ld fix(ld a){
	return a>Pi?a-2*Pi:(a<-Pi?a+2*Pi:a);
}
int cmp(ld a,ld b){
	return fabsl(a-b)<eps?0:a<b?-1:1;
}

const int N=100005;
ld d[N],k[N],b[N],dir[N],L[N],R[N],X[N],ox,oy,l,r=1e18,ans;
int id[N],n,cnt,aim,acc;

void create(ld r){
	cnt=0;
//	pr(r);
	rep(i,1,n){
		if(d[i]>r)continue;
		ld delta=acosl(d[i]/r);
		L[i]=fix(dir[i]-delta);
		R[i]=fix(dir[i]+delta);
		if(L[i]>R[i])swap(L[i],R[i]);
		id[++cnt]=i;
//		printf("%d  %.3Lf %.3Lf\n",i,L[i],R[i]);
	}
}

int a[N],c[N];
#define lb(x) (x&-x)
void upd(int x,int y){
	for(;x<N;x+=lb(x))c[x]+=y;
}
int qry(int x){
	int res=0;
	for(;x;x-=lb(x))res+=c[x];
	return res;
}
int calc(){
	int res=0,t=0; clr(c),clr(a);
	rep(i,1,cnt) X[++t]=L[id[i]],X[++t]=R[id[i]];
	sort(X+1,X+t+1);
	rep(i,1,cnt){
		int A=lower_bound(X+1,X+t+1,L[id[i]])-X;
		int B=lower_bound(X+1,X+t+1,R[id[i]])-X;
		a[A]=B;
	}
	rep(i,1,t)
		if(a[i]){
			res+=qry(a[i])-qry(i);
			if(res>aim)return aim+1;
			upd(a[i],1);
		}
//	qwq(res);
	return res;
}

set<pair<ld,int> > s;
void push(int u,int v){
	ld x=(b[u]-b[v])/(k[v]-k[u]);
	ld d=mo(x-ox,k[u]*x+b[u]-oy);
	if(d<r-eps)ans+=d,acc++;
}
void solve(){
	sort(id+1,id+cnt+1,[&](int a,int b){
		return L[a]<L[b];
	});
	rep(i,1,cnt){
		auto it=s.lower_bound(mp(L[id[i]],0));
		for(;it!=s.end()&&it->fi<R[id[i]];it++)
			push(id[i],it->se);
		s.insert(mp(R[id[i]],id[i]));
	}
}

int main(){
	read(n);
	read(ox),read(oy),read(aim);
	ox/=1000,oy/=1000;
	rep(i,1,n){
		read(k[i]),read(b[i]);
		k[i]/=1000,b[i]/=1000;
		ld A=k[i],B=-1,C=b[i];
		d[i]=fabsl(A*ox+B*oy+C)/mo(A,B);
		dir[i]=atanl(k[i])+(cmp(oy,k[i]*ox+b[i])<0?Pi/2:-Pi/2);
	}
	REP(T,100){
		ld mid=(l+r)*0.5;
		create(mid);
		if(calc()<aim)l=mid;
		else r=mid;
	}
//	pr(r);
	create(r),solve();
	ans+=(aim-acc)*r;
	printf("%.8lf\n",(double)ans);
	return 0;
}