Problem:
Problem F: Cutting a Chocolate
Turtle Shi-ta and turtle Be-ko decided to divide a chocolate.
The shape of the chocolate is rectangle. The corners of the chocolate are put on (0,0), (
w
,0), (
w
,
h
) and (0,
h
).
The chocolate has lines for cutting.
They cut the chocolate only along some of these lines.
The lines are expressed as follows.
There are
m
points on the line connected between (0,0) and (0,
h
), and between (
w
,0)  and (
w
,
h
).
Each
i
-th point, ordered by
y
value (
i
= 0 then
y
=0), is connected as cutting line.
These lines do not share any point where 0 <
x
<
w
.
They can share points where
x
= 0 or
x
=
w
.
However, (0,
l
i
)  =  (0,
l
j
)  and  (
w
,
r
i
)  =  (
w
,
r
j
)   implies
i
=
j
.
The following figure shows the example of the chocolate.
There are
n
special almonds, so delicious but high in calories on the chocolate.
Almonds are circle but their radius is too small. You can ignore radius of almonds.
The position of almond is expressed as  (
x
,
y
)  coordinate.
Two turtles are so selfish. Both of them have requirement for cutting.
Shi-ta's requirement is that the piece for her is continuous.
It is possible for her that she cannot get any chocolate.
Assume that the minimum index of the piece is
i
and the maximum is
k
.
She must have all pieces between
i
and
k
.
For example,  chocolate piece 1,2,3 is continuous but 1,3 or 0,2,4 is not continuous.
Be-ko requires that the area of her chocolate is at least
S
.
She is worry about her weight. So she wants the number of almond on her chocolate is as few as possible.
They doesn't want to make remainder of the chocolate because the chocolate is expensive.
Your task is to compute the minumum number of Beko's almonds if both of their requirment are satisfied.
Input
Input consists of multiple test cases.
Each dataset is given in the following format.
n
m
w
h
S
l
0
r
0
...
l
m-1
r
m-1
x
0
y
0
...
x
n-1
y
n-1
The last line contains five 0s.
n
is the number of almonds.
m
is the number of lines.
w
is the width of the chocolate.
h
is the height of the chocolate.
S
is the area that Be-ko wants to eat.
Input is integer except
x
i
y
i
.
Input satisfies following constraints.
1 ≤
n
≤ 30000
1 ≤
m
≤ 30000
1 ≤
w
≤ 200
1 ≤
h
≤ 1000000
0 ≤
S
≤
w*h
If
i
<
j
then
l
i
≤
l
j
and
r
i
≤
r
j
and then
i
-th lines and
j
-th lines share at most 1 point.
It is assured that
l
m-1
and
r
m-1
are
h
.
x
i
y
i
is floating point number with ten digits.
It is assured that they are inside of the chocolate.
It is assured that the distance between points and any lines is at least 0.00001.
Output
You should output the minumum number of almonds for Be-ko.
Sample input
2 3 10 10 50
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 70
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 30
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 40
3 3
6 6
10 10
4.0000000000 4.0000000000
7.0000000000 7.0000000000
2 3 10 10 100
3 3
6 6
10 10
4.0000000000 4.00
...(truncated)

Submitted solutions:

code_snippet: #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define MAXN 30050
#define eps 1e-8
typedef struct point {
    double x,y;
	point (){
  
	}
	point (double xx,double yy){
          x = xx;
		  y = yy;
	}
	void setxy(double xx,double yy){
		x = xx;
		y = yy;
	}
	point operator-(point aa){
        return point (x-aa.x,y-aa.y);
	}
	void read(){
		scanf("%lf%lf",&x,&y);
	}
};
typedef struct Lines{
    point st,ed;
	void setp(point aa,point bb){
		st = aa;
		ed = bb;
	}
};
typedef point Vector;
typedef struct node{
    double s,pres;
	int chm,prechm;
	double lh,rh;
	point LP,RP;
	void init(){
       s = pres = 0.0;
	   chm = prechm = 0;
	}
	void read(){
      scanf("%lf%lf",&lh,&rh);
	}
	void setlr(double Lx,double Rx){
		LP.setxy(Lx,lh);
		RP.setxy(Rx,rh);
	}
};
node no[MAXN];
point chmo[MAXN];
Lines LL[MAXN];
double Cross(point aa,point bb){
    return aa.x*bb.y-aa.y*bb.x;
}
int dcmp(double x){
   if(fabs(x)<eps) return 0;
   return x<0?-1:1;
}
double prearea(point aa,point bb,point cc,point dd){
      double area1 = fabs(Cross(aa-bb,dd-bb));
	  double area2 = fabs(Cross(dd-bb,cc-bb));
	  return (area1+area2)/2;
}
void presoch(int n,int m,int k){
	   int L,R,Mid;
	  for(int i=0;i<n;++i){
		 L = 1;R = m;
		 while(L<R){
			 Mid = (L+R)>>1;
			 if(dcmp(Cross(LL[Mid].st - chmo[i],LL[Mid].ed-chmo[i]))<=0)
				 R = Mid;
			 else L = Mid+1;
		 }
		 while(1){
			 if(dcmp(Cross(LL[L].st - chmo[i],LL[L].ed-chmo[i]))>0)
				 --L;
			 else break;
		 }
		 no[L-1].chm++;
	  }
	  no[0].prechm = no[0].chm;
	  for(int i=1;i<=k;++i){
             no[i].prechm = no[i].chm+no[i-1].prechm;
	  }
	//  return L;
}
double gets(int ind1,int ind2){

      if(!ind1){
		  return no[ind2].pres;
	  }
	   return (no[ind2].pres - no[ind1-1].pres); 
}
int getch(int L,int R){
        if(!L){
			return no[R].prechm;
		}
		return no[R].prechm - no[L-1].prechm;
}
int solve(int n,int m,double S){

	int ans = n;
	int L,R,Mid;
	double AS = no[m].pres - S;
	double ALLS = no[m].pres;
	int Chms = no[m].prechm;
	double tmps;
	int tmpch;
	for(int i=0;i<=m;++i){
		L = i;
		R = m;
		while(L<R){
			Mid = (L+R)>>1;
			tmps = gets(i,Mid);
			if(dcmp(tmps-AS)>0){
				R = Mid;
			}
			else {
				L = Mid+1;
			}
		}
		//找到了

		while(L>=i){
		tmps = gets(i,L);
		tmps = ALLS -tmps;
		if(dcmp(tmps-S)>=0){
			tmpch = Chms -  getch(i,L);
			if(tmpch<ans){ans = tmpch;}
			break;
		}
		--L;
		}
	}
	return ans;
}
int main(){
	int n,m;
	double w,h,S;
	point dwL,dwR,upL,upR;
	while(scanf("%d%d",&n,&m)!=EOF){
		scanf("%lf%lf%lf",&w,&h,&S);
		if(!n&&!m&&!w&&!h&&!S)break;
		dwL.setxy(0,0);
		dwR.setxy(w,0);
		LL[0].setp(dwL,dwR);
		upL.setxy(0,h);
		upR.setxy(w,h);
		LL[m+1].setp(upL,upR);
		for(int i=0;i<m;++i){
			no[i].read();
			no[i].setlr(0,w);
			no[i].init();
			LL[i+1].setp(no[i].LP,no[i].RP);
		}
		no[m].init();
		for(int i=0;i<n;++i){
			chmo[i].read();
		}
		double area = prearea(no[0].LP,dwL,dwR,no[0].RP);
		no[0].s = area;
		no[0].pres = area;
		int tmpup = m-1;
		for(int i=1;i<=tmpup;++i){
		   no[i].s = prearea(no[i].LP,no[i-1].LP,no[i-1].RP,no[i].RP);
		   no[i].pres = no[i].s+no[i-1].pres;
		}
		if(m>=1){
		no[m].s  = prearea(upL,no[m-1].LP,no[m-1].RP,upR);
		no[m].pres=no[m].s+no[m-1].pres;
		}
		//杏仁数
		presoch(n,m+2,m);
		int ans = solve(n,m,S);
		printf("%d\n",ans);
	}
	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 6384
final_rank: 17

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 1067.cc: Problem F: Cutting a Chocolate
 */

#include<cstdio>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 30000;
const int MAX_M = 30000;
const int INF = 1 << 30;

/* typedef */

/* global variables */

int ls[MAX_M + 1], rs[MAX_M + 1], cs[MAX_M], css[MAX_M + 1];
double xs[MAX_N], ys[MAX_N], ss[MAX_M + 1];

/* subroutines */

/* main */

int main() {
  int n, m, w, h, s;
  while (scanf("%d%d%d%d%d", &n, &m, &w, &h, &s), n > 0) {
    ls[0] = rs[0] = 0;
    for (int i = 1; i <= m; i++) scanf("%d%d", ls + i, rs + i);
    for (int i = 0; i < n; i++) scanf("%lf%lf", xs + i, ys + i);

    ss[0] = 0.0;
    for (int i = 0; i < m; i++) {
      double si = 0.5 * (ls[i + 1] - ls[i] + rs[i + 1] - rs[i]) * w;
      ss[i + 1] = ss[i] + si;
    }

    fill(cs, cs + m, 0);
    for (int i = 0; i < n; i++) {
      int j0 = 0, j1 = m;
      while (j0 + 1 < j1) {
	int j = (j0 + j1) / 2;
	double lyi = ls[j] + (double)(rs[j] - ls[j]) / w * xs[i];
	if (lyi > ys[i]) j1 = j;
	else j0 = j;
      }
      cs[j0]++;
    }
    for (int i = 0; i < m; i++) css[i + 1] = css[i] + cs[i];
    //for (int i = 0; i < m; i++) printf("%d ", cs[i]); putchar('\n');

    int mina = INF;
    for (int i = 0, j = 0; i < m; i++) {
      j = max(i, j);
      while (j < m && ss[m] - (ss[j + 1] - ss[i]) >= s) j++;

      if (ss[m] - (ss[j] - ss[i]) >= s)
	mina = min(mina, css[i] + (css[m] - css[j]));
    }

    printf("%d\n", mina);
  }
  
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 3996
final_rank: 7

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

// #define DEBUG_PRINTF
// #define DEBUG_PRINT_ERROR

static long n, m, w, h, S;

// �_�������̏㑤���ǂ���
bool bIsUpper( long l, long r, double x, double y ) {
    double dirL[2] = { (double)w, (double)r-l };
    double dirP[2] = { (double)x, (double)y-l };
    return ( dirL[0]*dirP[1] - dirL[1]*dirP[0] > 0.0 );
}

// �_���܂܂�Ă����Ԃ̔ԍ�
long FindSegment( const vector< pair<long, long> >& vSeg, double x, double y )
{
    long max = m-1;
    long min = 0;
    long i = (max-min)/2 + min;
    while ( max > min ) {
        if ( bIsUpper( vSeg[i].first, vSeg[i].second, x, y ) ) {
            min = i;
        } else {
            max = i;
        }
        if ( max-min == 1 ) {
            if ( min == 0 ) {
                if ( bIsUpper( vSeg[0].first, vSeg[0].second, x, y ) ) {
                    return 1;
                }
                return 0;
            }
            return max;
        }
        i = (max-min)/2 + min;
    }

    // for ( long i = 0; i < m; ++i ) {
    //     if ( !bIsUpper( vSeg[i].first, vSeg[i].second, x, y ) ) {
    //         return i;
    //     }
    // }
    // error
#ifdef DEBUG_PRINT_ERROR
    cout << "error" << endl;
#endif
    return m-1;
}

double CalcArea( const vector<double>& vS, long min, long max )
{
    if ( min > 0 ) {
        return w*h - ( vS[max] - vS[min-1] );
    }
    return w*h - vS[max];
    // double s = 0.0;
    // for ( long i = min; i <= max; ++i ) {
    //     s += vS[i];
    // }
    // return w*h - s;
}

long FindMaxArea( const vector<double>& vS, const long Min )
{
    long max = m-1;
    long min = Min;
    double a0 = CalcArea( vS, min, min );
    if ( a0 < S ) {
        return -1;
    }
    double a1 = CalcArea( vS, min, max );
    if ( a1 >= S ) {
        return max;
    }

    long i = (max-min)/2 + min;
    while ( max != min ) {
        double a = CalcArea( vS, Min, i );
        if ( a < S ) {
            max = i;
        } else {
            min = i;
        }
        if ( max-min == 1 ) {
            return min;
        }
        i = (max-min)/2 + min;
    }

    // for ( long i = 0; i < m; ++i ) {
    //     if ( !bIsUpper( vSeg[i].first, vSeg[i].second, x, y ) ) {
    //         return i;
    //     }
    // }
    // error
    // cout << "error" << endl;
    return -1;
}


long CountAlmond( const vector<long>& vAd, long min, long max )
{
    long nn = 0;
    if ( max == m-1 ) {
        return n - vAd[min];
    }
    return n - ( vAd[min] - vAd[max+1] );
    // long nn = 0;
    // for ( long i = min; i <= max; ++i ) {
    //     nn += vAd[i];
    // }
    // return n - nn;
}


int main()
{
    while ( 1 ) {
    cin >> n;
    cin >> m;
    cin >> w;
    cin >> h;
    cin >> S;

    if ( n == 0 ) {
        break;
    }
    vector< pair<long, long> > vSeg(m);
    for ( long i = 0; i < m; ++i ) {
        cin >> vSeg[i].first;
        cin >> vSeg[i].second;
        // cout << vSeg[i].first << " " << vSeg[i].second << endl;
    }
    vector<long> vAdCount(m, 0);
    for ( long i = 0; i < n; ++i ) {
        double x, y;
        cin >> x;
        cin >> y;
#ifdef DEBUG_PRINTF
        cout << "i=" << i << " " << x << " " << y << endl;
#endif
        vAdCount[ FindSegment( vSeg, x, y ) ] += 1;
#ifdef DEBUG_PRINTF
        cout << x << " " << y << "  index : " << FindSegment( vSeg, x, y ) << endl;
#endif
    }
    for ( long i = m-2; i >= 0; --i ) {
        vAdCount[i] += vAdCount[i+1];
    }
    vector<double> vS(m);
    for ( long i =0; i < m; ++i ) {
        if ( i == 0 ) {
            vS[i] = ( vSeg[0].first + vSeg[0].second ) * w / 2.0;
        } else {
            vS[i] = ( vSeg[i].first + vSeg[i].second - vSeg[i-1].first - vSeg[i-1].second ) * w / 2.0;
        }
    }
    for ( long i =1; i < m; ++i ) {
        vS[i] += vS[i-1];
    }
    double dTol = w*h - S;

    long nAns = n;
    for ( long min = 0; min < m; ++min ) {
        long max;
        // cout << "min " << min << endl;
        for ( max = min; max < m; ++max ) {
            // cout << "max " << max << endl;
            double s = CalcArea( vS, min, max );
            if ( s < S ) {
                break;
            }
        }
        --max;
        if ( min > max ) {
            continue;
        }
#ifdef DEBUG_PRINTF
        cout << "max- " << max << endl;
#endif
        // long max = FindMaxArea( vS, min );
        max = FindMaxArea( vS, min );
        if ( max < 0 ) {
            continue;
        }
#ifdef DEBUG_PRINTF
        cout << "max  " << max << endl;
#endif
        long nAlmond = CountAlmond( vAdCount, min, max );
        // cout << "nAr " << nAlmond << endl;
        if ( nAlmond < nAns ) {
            nAns = nAlmond;
        }
    }

#ifdef DEBUG_PRINTF
    cout << "---------------" << endl;
#endif
    cout << nAns << endl;
#ifdef DEBUG_PRINTF
    cout << "---------------" << endl;
#endif
    }
    return 0;
}
accuracy: 1
time_ms: 3080
memory_kb: 4040
final_rank: 20

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#pragma warning(disable : 4996)

using ll = long long;
using namespace std;

const int INF = 2140000000;
const long long LINF = 9223300000000000000;
const long long MOD = 1000000007;


void solve()
{
    while (1) {
        int n, m, w, h, S;
        scanf("%d%d%d%d%d", &n, &m, &w, &h, &S);
        if (n + m + w + h + S == 0) break;
        S *= 2;
        int S2 = h * w *2- S;

        vector<int> L(m), R(m);
        vector<double> X(n), Y(n);
        for (int i = 0; i < m; i++) {
            scanf("%d%d", &L[i], &R[i]);
        }
        for (int i = 0; i < n; i++) {
            scanf("%lf%lf", &X[i], &Y[i]);
        }

        vector<int> nn(m), snn(m+1);
        for (int i = 0; i < n; i++) {
            int l = -1, r = m;
            while (r - l > 1) {
                int mm = (l + r) / 2;

                double x0 = w, y0 = R[mm] - L[mm];
                double x1 = X[i], y1 = Y[i] - L[mm];
                double chk = x0*y1 - x1*y0;
                if (chk < 0) {
                    r = mm;
                }
                else {
                    l = mm;
                }
            }
            //printf("[%d]%d\n", i, r);
            nn[r]++;
        }
        for (int i = 0; i < m; i++) {
            snn[i + 1] = snn[i] + nn[i];
        }

        vector<int> vs(m), svs(m + 1);
        for (int i = 0; i < m; i++) {
            if (i == 0) {
                vs[i] = (L[i] + R[i])*w;
            }
            else {
                vs[i] = (L[i] - L[i - 1] + R[i] - R[i - 1])*w;
            }
            svs[i + 1] = svs[i] + vs[i];
        }

        int ans = 0;
        for (int i = 0; i <= m; i++) {
            int tmp = svs[i] + S2 + 1;
            int k = lower_bound(svs.begin(), svs.end(), tmp) - svs.begin();
            k--;
            if (k >= i) {
                int ss = svs[k] - svs[i];
                assert(ss >= 0 && ss <= S2);
                int ans0=snn[k] - snn[i];
                ans = max(ans, ans0);
            }
        }
        printf("%d\n", n-ans);
    }

    return;
}

int main()
{
    solve();

    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 3856
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <algorithm>
#include <numeric>
#include <tuple>

using namespace std;

typedef long long ll;

constexpr int INF = 1 << 30;
constexpr ll INFLL = 1LL << 60;
constexpr ll MOD = 1'000'000'007;

int main()
{
    while (1) {
        int N;
        cin >> N;
        if (N == 0) break;
        int M, W, H, S;
        cin >> M >> W >> H >> S;

        vector<int> L(M), R(M);
        for (int m = 0; m < M; ++m) cin >> L[m] >> R[m];

        vector<int> A(M + 1);   // Accumultated area
        for (int m = 1; m <= M; ++m) {
            A[m] = W * (L[m - 1] + R[m - 1]);
        }

        vector<int> C(M);
        for (int n = 0; n < N; ++n) {
            double X, Y;
            cin >> X >> Y;
            int l = -1, r = M;
            while (r - l > 1) {
                int m = l + (r - l) / 2;
                if (Y < double(R[m] - L[m]) / W * X + L[m]) r = m;
                else l = m;
            }
            ++C[r];
        }
        vector<int> AC(M + 1);
        for (int m = 0; m < M; ++m) {
            AC[m + 1] = AC[m] + C[m];
        }

        int Ans = INF;
        for (int l = 0; l <= M; ++l) {
            int r = upper_bound(A.begin(), A.end(), A[l] + 2 * (W * H - S)) - A.begin() - 1;
            Ans = min(Ans, N - AC[r] + AC[l]);
        }
        cout << Ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 3648
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int l[31000];
int r[31000];
double x[31000];
double y[31000];
int h[31000];
int s[31000];
int sum[31000];
int hsum[31000];
int main(){
	while(true){
//        ll n,m,h,w,s;
//        cin >> n >> m >> h >> w >> s;
        ll a,b,c,d,e;
        cin >> a >> b >> c >> d >> e;
        if(a==0){
            return 0;
        }
        
		for(int i=0;i<b;i++){
			scanf("%d%d",l+i,r+i);
		}
		for(int i=0;i<b;i++)h[i]=0;
		for(int i=0;i<b;i++){
			if(i)s[i]=(l[i]+r[i]-l[i-1]-r[i-1])*c;
			else s[i]=(l[0]+r[0])*c;
		}
		sum[0]=s[0];
		for(int i=1;i<b;i++){
			sum[i]=sum[i-1]+s[i];
		}
		for(int i=0;i<a;i++)scanf("%lf%lf",x+i,y+i);
		e*=2;
		for(int i=0;i<a;i++){
			int L=0;
			int R=b;
			while(L+1<R){
				int M=(L+R)/2;
				double at=(double)l[M-1]+(double)(r[M-1]-l[M-1])/c*x[i];
				if(at>y[i])R=M;
				else L=M;
			}
			h[L]++;
		}
		for(int i=0;i<=b;i++)hsum[i]=0;
		for(int i=0;i<b;i++)hsum[i+1]=hsum[i]+h[i];
		int ret=999999999;
		int now=0;
		for(int i=0;i<b;i++){
			//if(c*d*2-now<e)break;
			int to=upper_bound(sum,sum+b,now+c*d*2-e)-sum;
			ret=min(ll(ret),ll(a-(hsum[to]-hsum[i])));
			now+=s[i];
		}
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 180
memory_kb: 4380
final_rank: 10

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
int l[31000];
int r[31000];
double x[31000];
double y[31000];
int h[31000];
int s[31000];
int sum[31000];
int hsum[31000];
int main(){
	int a,b,c,d,e;
	while(scanf("%d%d%d%d%d",&a,&b,&c,&d,&e),a){
		for(int i=0;i<b;i++){
			scanf("%d%d",l+i,r+i);
		}
		for(int i=0;i<b;i++)h[i]=0;
		for(int i=0;i<b;i++){
			if(i)s[i]=(l[i]+r[i]-l[i-1]-r[i-1])*c;
			else s[i]=(l[0]+r[0])*c;
		}
		sum[0]=s[0];
		for(int i=1;i<b;i++){
			sum[i]=sum[i-1]+s[i];
		}
		for(int i=0;i<a;i++)scanf("%lf%lf",x+i,y+i);
		e*=2;
		for(int i=0;i<a;i++){
			int L=0;
			int R=b;
			while(L+1<R){
				int M=(L+R)/2;
				double at=(double)l[M-1]+(double)(r[M-1]-l[M-1])/c*x[i];
				if(at>y[i])R=M;
				else L=M;
			}
			h[L]++;
		}
		for(int i=0;i<=b;i++)hsum[i]=0;
		for(int i=0;i<b;i++)hsum[i+1]=hsum[i]+h[i];
		int ret=999999999;
		int now=0;
		for(int i=0;i<b;i++){
			//if(c*d*2-now<e)break;
			int to=upper_bound(sum,sum+b,now+c*d*2-e)-sum;
			ret=min(ret,a-(hsum[to]-hsum[i]));
			now+=s[i];
		}
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 180
memory_kb: 3892
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll,ll> mp;
ll inf =  1e9;
#define EPS 1e-12

struct point{
    double x,y;
    point(){}
    point(double x,double y):x(x),y(y){}
    point operator + (point p){ return point(x+p.x,y+p.y);}
    point operator - (point p){ return point(x-p.x,y-p.y);}
    void make(){ cin>>x>>y; }
};

double cross(point a,point b){return a.x*b.y - a.y*b.x; }

int ccw(point p0,point p1,point p2){
    point a = p1-p0;
    point b = p2-p0;
    if( cross(a,b) > EPS )return 1;
    else return -1;
}
struct line{
    point s,t;
    line(){}
    line(point s,point t):s(s),t(t){}
};
int main(){
    while(1){
	int n,m,w,h,S;
	cin>>n>>m>>w>>h>>S;
	if(n==0)break;
	point p0 = point(0,0);
	point p1 = point(w,0);
	point p2 = point(0,h);
	point p3 = point(w,h);
	vector<line> ls(m+2);
	vector<double> l(m),r(m),s(m+1);
	ls[0] = line(p0,p1);
	s[0] = 0;
	for(int i=0;i<m;i++){
	    cin>>l[i]>>r[i];
	    s[i+1] = (((double)(l[i]+r[i]))*w)/2.0;
	    ls[i+1] = line( point(0,l[i]),point(w,r[i]) );
	}
	ls[m+1] = line(p2,p3);
	//s[m+1] = w*h;
	vector<int> cnt(m+1,0);
	for(int i=0;i<n;i++){
	    point p;
	    p.make();
	    int upper = m+1,low = 0;
	    while(upper-low>1){
		int mid = (upper+low)/2;
		if( ccw(ls[mid].s,ls[mid].t,p) * ccw(ls[mid+1].s,ls[mid+1].t,p) <= -1 )break;
		if( ccw(ls[mid].s,ls[mid].t,p) > 0 ) low =mid;
		else upper= mid;
	    }
	    int mid = (upper+low)/2;
	 //   if( ccw(ls[mid].s,ls[mid].t,p) * ccw(ls[mid+1].s,ls[mid+1].t,p) <= -1 ) cnt[mid]++;
	    cnt[ mid+1 ]++;
	    //if( mid< m+1&&ccw(ls[mid].s,ls[mid].t,p) * ccw(ls[mid+1].s,ls[mid+1].t,p) <= -1 ) cnt[mid]++;
	}
	for(int i=0;i<m;i++) cnt[i+1] +=cnt[i];
	int res = 0;
	//for(int i=0;i<=m+1;i++){
	  //  cout<<cnt[i]<<' '<<s[i]<<endl;
	//}
	for(int i=0;i<m;i++){
	    double ss = s[i];
	    int cc = cnt[i];
	    auto it = upper_bound(s.begin(),s.end(),w*h - S+ss );
	    //if(it == s.end() ) continue;
	    it--;
	    int index = it-s.begin();
	    res = max(res, cnt[index]-cc);
	}
	cout<<n-res<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 4932
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll,ll> mp;
ll inf =  1e9;
#define EPS 1e-12

struct point{
    double x,y;
    point(){}
    point(double x,double y):x(x),y(y){}
    point operator + (point p){ return point(x+p.x,y+p.y);}
    point operator - (point p){ return point(x-p.x,y-p.y);}
    void make(){ cin>>x>>y; }
};

double cross(point a,point b){return a.x*b.y - a.y*b.x; }

int ccw(point p0,point p1,point p2){
    point a = p1-p0;
    point b = p2-p0;
    if( cross(a,b) > EPS )return 1;
    else return -1;
}
struct line{
    point s,t;
    line(){}
    line(point s,point t):s(s),t(t){}
};
int main(){
    while(1){
	int n,m,w,h,S;
	cin>>n>>m>>w>>h>>S;
	if(n==0)break;
	point p0 = point(0,0);
	point p1 = point(w,0);
	point p2 = point(0,h);
	point p3 = point(w,h);
	vector<line> ls(m+2);
	vector<double> l(m),r(m),s(m+2);
	ls[0] = line(p0,p1);
	s[0] = 0;
	for(int i=0;i<m;i++){
	    cin>>l[i]>>r[i];
	    s[i+1] = (((double)(l[i]+r[i]))*w)/2.0;
	    ls[i+1] = line( point(0,l[i]),point(w,r[i]) );
	}
	ls[m+1] = line(p2,p3);
	s[m+1] = w*h;
	vector<int> cnt(m+2,0);
	for(int i=0;i<n;i++){
	    point p;
	    p.make();
	    int upper = m+1,low = 0;
	    while(upper-low>1){
		int mid = (upper+low)/2;
		if( ccw(ls[mid].s,ls[mid].t,p) * ccw(ls[mid+1].s,ls[mid+1].t,p) <= -1 )break;
		if( ccw(ls[mid].s,ls[mid].t,p) > 0 ) low =mid;
		else upper= mid;
	    }
	    int mid = (upper+low)/2;
	 //   if( ccw(ls[mid].s,ls[mid].t,p) * ccw(ls[mid+1].s,ls[mid+1].t,p) <= -1 ) cnt[mid]++;
	    cnt[ mid +1]++;
	    //if( mid< m+1&&ccw(ls[mid].s,ls[mid].t,p) * ccw(ls[mid+1].s,ls[mid+1].t,p) <= -1 ) cnt[mid]++;
	}
	for(int i=0;i<=m;i++) cnt[i+1] +=cnt[i];
	int res = 0;
	//for(int i=0;i<=m+1;i++){
	  //  cout<<cnt[i]<<' '<<s[i]<<endl;
	//}
	for(int i=0;i<m+1;i++){
	    double ss = s[i];
	    int cc = cnt[i];
	    auto it = upper_bound(s.begin(),s.end(),w*h - S+ss );
	    //if(it == s.end() ) continue;
	    it--;
	    int index = it-s.begin();
	    res = max(res, cnt[index]-cc);
	}
	cout<<n-res<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 5000
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <tuple>

using namespace std;

class Solver {
};


int main() {
	while (true) {
		int n, m, w, h, s;
		cin >> n >> m >> w >> h >> s;
		if (n == 0)break;

		vector<int> ls(m);
		vector<int> rs(m);
		for (int i = 0; i < m; i++) {
			cin >> ls[i] >> rs[i];
		}

		vector<tuple<double, double>> xys;
		for (int i = 0; i < n; i++) {
			double x, y;
			cin >> x >> y;
			xys.emplace_back(x, y);
		}

		vector<double> range_s(m);
		vector<int> range_cnt(m, 0);
		double s_sum = 0;
		for (int i = 0; i < m; i++) {
			double s_tmp = (ls[i] + rs[i]) * 0.5 * w;
			range_s[i] = s_tmp - s_sum;
			s_sum = s_tmp;
		}

		for (int i = 0; i < n; i++) {
			int bottom = -1;
			int top = m - 1;
			double x, y;
			tie(x, y) = xys[i];
			while (bottom + 1 < top) {
				int mid = (bottom + top + 1) / 2;

				double yy = (rs[mid] - ls[mid]) * x / w + ls[mid];
				if (yy >= y)top = mid;
				else bottom = mid;
			}

			range_cnt[top]++;
		}

		vector<int> sums(m, 0);
		sums[0] = range_cnt[0];
		for (int i = 1; i < m; i++) {
			sums[i] = sums[i - 1] + range_cnt[i];
		}

		int res = n;
		for (int i = 0; i < m; i++) {
			int bottom = i;
			int top = m;
			while (bottom + 1 < top) {
				int mid = (bottom + top) / 2;
				int l_delta = ls[mid];
				int r_delta = rs[mid];
				if (i > 0) {
					l_delta -= ls[i - 1];
					r_delta -= rs[i - 1];
				}
				double sum_tmp = (l_delta + r_delta) * 0.5 * w;
				double remain_s = h * w - sum_tmp;

				if (remain_s >= s)bottom = mid;
				else top = mid;
			}

			double l_d = ls[bottom];
			double r_d = rs[bottom];
			if (i > 0) {
				l_d -= ls[i - 1];
				r_d -= rs[i - 1];
			}
			double sum = (l_d + r_d) * 0.5 * w;
			if (w * h - sum < s)continue;

			int tmp = sums[m - 1] - sums[bottom];
			if (i > 0)tmp += sums[i - 1];
			res = min(res, tmp);
		}

		cout << res << endl;
	}
}
accuracy: 1
time_ms: 480
memory_kb: 4096
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <complex>
using namespace std;
using W = double;
using P = complex<W>;
using L = pair<P,P>;

#define X real()
#define Y imag()

constexpr W EPS = 1e-8;

W cross(const P& a, const P& b){
  return a.X*b.Y - a.Y*b.X;
}

bool is_below(const L &l, const P &p){
  P d = l.second - l.first;
  P q = p - l.first;
  return cross(d,q) < EPS;
}

int main(){
  int n, m;
  W w, h, s;
  while(cin >> n >> m >> w >> h >> s, n){
    vector<L> lines;
    lines.emplace_back(P(0,0),P(w,0));

    vector<W> S(m+2,0);
    for(int i = 0; i < m; ++i){
      W l, r;
      cin >> l >> r;
      lines.emplace_back(P(0,l),P(w,r));
      S[i+1] = (l+r)/2*w;
    }

    lines.emplace_back(P(0,h),P(w,h));
    S[m+1] = w*h;

    for(int i = m+1; i > 0; --i) S[i] -= S[i-1];

    vector<int> C(m+2,0);
    for(int i = 0; i < n; ++i){
      W x, y;
      cin >> x >> y;
      P a(x,y);
      int ng = 0, ok = m+1;
      while(ok - ng > 1){
	int m = (ok+ng)/2;
	if(is_below(lines[m],a)){
	  ok = m;
	}else{
	  ng = m;
	}
      }
      ++C[ok];
      // cerr << i << " " << ok << endl;
    }

    double curS = 0, lim = h * w - s;
    int curA = 0, ub = 0, ans = n;
    for(int lb=0; lb<m+2; lb++) {
      while(ub < m+2 and (curS + S[ub] <= lim + EPS)) {
	curS += S[ub]; curA += C[ub];
	ub++;
      }
      // fprintf(stderr, "[%d, %d): curS = %.12f, curA = %d\n", lb, ub, curS, curA);
      ans = min(ans, n - curA);

      if(lb == ub) {
	ub++;
      }
      else {
	curS -= S[lb];
	curA -= C[lb];
      }
    }

    /*
    cerr << "S" << endl;
    for(auto s : S) cerr << s << " " ;
    cerr << endl;

    cerr << "C" << endl;
    for(auto c : C) cerr << c << " " ;
    cerr << endl;
    */
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 520
memory_kb: 4904
final_rank: 14

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()
typedef complex<double> P;
typedef vector<P> VP;

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}
double getarea(const VP &poly){
    double ret = 0;
    for (int i=0; i<(int)poly.size(); i++){ 
        ret += cross(poly[i], poly[(i+1)%poly.size()]);
    }
    return ret*0.5;
}

int main(){
    while(1){
        int n,m,w,h,s;
        cin >> n >> m >> w >> h >> s;
        if(n==0) break;

        vector<double> l(m+1, 0), r(m+1, 0);
        for(int i=1; i<=m; i++){
            cin >> l[i] >> r[i];
        }
        VP p(n);
        for(int i=0; i<n; i++){
            double x,y;
            cin >> x >> y;
            p[i] = P(x, y);
        }

        vector<double> area(m+1, 0);
        for(int i=1; i<=m; i++){
            VP poly = {P(0, l[i-1]), P(w, r[i-1]), P(w, r[i]), P(0, l[i])};
            area[i] = getarea(poly);
            area[i] += area[i-1];
        }
        vector<int> num(m+1, 0);
        for(int i=0; i<n; i++){
            int ub=m, lb=0;
            while(lb +1 < ub){
                int mid = (lb +ub)/2;
                if(ccw(P(0, l[mid]), P(w, r[mid]), p[i]) == 1){
                    lb = mid;
                }else{
                    ub = mid;
                }
            }
            num[ub]++;
        }
        for(int i=0; i<m; i++){
            num[i+1] += num[i];
        }

        int ans = 1e9;
        for(int i=0; i<m; i++){
            if(area[i] +EPS >= s){
                ans = min(ans, num[i]);
                break;
            }
            int lb=i, ub=m;
            while(lb +1 < ub){
                int mid = (lb +ub)/2;
                if(h*w -(area[mid] -area[i]) +EPS > s){
                    lb = mid;
                }else{
                    ub = mid;
                }
            }
            ans = min(ans, n-(num[lb] -num[i]));
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 4272
final_rank: 13

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 30005

class Point{
public:
	double x,y;

	Point(double x = 0,double y = 0):x(x),y(y){}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}
};

typedef Point Vector;
typedef vector<Point> Polygon;

struct Info{
	int value;
	Polygon polygon;
	double min_y,max_y,S;
};

int num_almond,num_section;
int ruiseki_value[NUM];
double W,H,total_S,need_S;
double ruiseki_S[NUM];
Info info[NUM];
Point pre_L,pre_R,L,R;

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

//ベクトルaとbの外積を求める関数
double cross(Vector a,Vector b){
	return a.x*b.y-a.y*b.x;
}

//ベクトルaとbの内積を求める関数
double dot(Vector a,Vector b){
	return a.x*b.x + a.y*b.y;
}

Point calc_minus(Point a,Point b){
	Point ret;

	ret.x = a.x-b.x;
	ret.y = a.y-b.y;

	return ret;
}

/*
 * IN 2
 * ON 1
 * OUT 0
 *
 */
int contains(Polygon g,Point p){
	int n = g.size();
	bool x = false;
	for(int i = 0; i < n; i++){
		Point a = g[i]-p,b = g[(i+1)%n]-p;
		if(abs(cross(a,b)) < EPS && dot(a,b) < EPS)return 1;
		if(a.y > b.y)swap(a,b);
		if(a.y < EPS && EPS < b.y && cross(a,b) > EPS) x = !x;
	}
	return (x ? 2:0);
}

void func(){

	for(int i = 0; i < num_section; i++){
		info[i].value = 0; //断片内のアーモンドの個数
		info[i].polygon.clear();
	}

	pre_L.x = 0;
	pre_R.x = W;

	pre_L.y = 0;
	pre_R.y = 0;

	L.x = 0;
	R.x = W;

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

		scanf("%lf %lf",&L.y,&R.y);

		//左下から反時計回りに点を記録
		info[i].polygon.push_back(pre_L);
		info[i].polygon.push_back(pre_R);
		info[i].polygon.push_back(R);
		info[i].polygon.push_back(L);

		info[i].min_y = min(pre_L.y,pre_R.y);
		info[i].max_y = max(L.y,R.y);

		info[i].S = (((L.y-pre_L.y)+(R.y-pre_R.y))*W)/2.0; //台形の面積

		pre_L = L;
		pre_R = R;
	}

	//アーモンドの処理
	Point tmp;
	int left,right,m;
	int min_index,max_index;

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

		scanf("%lf %lf",&tmp.x,&tmp.y);

		//アーモンドが所属し得る最小のインデックスを求める
		left = 0,right = num_section-1,m = (left+right)/2;
		min_index = num_section-1;

		while(left <= right){
			if(info[m].max_y > tmp.y){

				min_index = m;
				right = m-1;

			}else{

				left = m+1;

			}
			m = (left+right)/2;
		}

		//アーモンドが所属し得る最大のインデックスを求める
		left = 0,right = num_section-1,m = (left+right)/2;
		max_index = 0;

		while(left <= right){

			if(info[m].min_y < tmp.y){

				max_index = m;
				left = m+1;

			}else{

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

		if(min_index > max_index)continue;

		for(int i = min_index; i <= max_index; i++){

			if(contains(info[i].polygon,tmp) == 2){ //問題仕様上、ONは無いはず
				info[i].value++;
				break;
			}
		}
	}

	//累積和テーブルを作成する
	ruiseki_S[0] = info[0].S;
	ruiseki_value[0] = info[0].value;

	for(int i = 1; i < num_section; i++){
		ruiseki_S[i] = info[i].S;
		ruiseki_S[i] += ruiseki_S[i-1];
		ruiseki_value[i] = info[i].value;
		ruiseki_value[i] += ruiseki_value[i-1];
	}

	total_S = H*W;
	int ans = num_almond;

	double tmp_S;
	int tmp_almond;

	for(int i = 0; i < num_section; i++){
		/*★シータの面積は大きいほど良い★*/

		//2分探索で、残チョコの面積がS以上となる、最大の上端を求める
		left = 0,right = num_section-1,m = (left+right)/2;

		while(left <= right){
			//シータの面積を求める
			if(i != 0){

				tmp_S = ruiseki_S[m]-ruiseki_S[i-1];

			}else{

				tmp_S = ruiseki_S[m];
			}

			if(total_S-tmp_S >= need_S){ //残りがneed_S以上

				if(i != 0){

					tmp_almond = ruiseki_value[m]-ruiseki_value[i-1];

				}else{

					tmp_almond = ruiseki_value[m];
				}

				ans = min(ans,num_almond-tmp_almond);

				left = m+1;

			}else{
				right = m-1;
			}
			m = (left+right)/2;
		}
	}
	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d %lf %lf %lf",&num_almond,&num_section,&W,&H,&need_S);
		if(num_almond == 0 && num_section == 0)break;

		func();
	}
	return 0;
}
accuracy: 1
time_ms: 490
memory_kb: 7540
final_rank: 18

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class t>
using table = vector<vector<t>>;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"
  
void getnum(const int l, const int r, const vector<pair<ld, ld>>&armonds, const vector<pair<ld, ld>>&lines,vector<pair<int,ld>>&areas) {
	if (l + 1 == r) {
		areas[l].first = armonds.size();
	}
	else {
		int m = (l + r) / 2;
		pair<ld, ld>line(lines[m]);
		vector<pair<ld, ld>>larmonds, rarmonds;
		for (auto armond : armonds) {
			ld ay = line.first + line.second*armond.first;
			if (ay > armond.second) {
				larmonds.emplace_back(armond);
			}
			else {
				rarmonds.emplace_back(armond);
			}
		}
		getnum(l, m, larmonds, lines, areas);
		getnum(m, r, rarmonds, lines, areas);
	}
}

int main() {
	while (1) {
		int N, M, W, H, S; cin >> N >> M >> W >> H >> S;
		if (!N)break;
		vector<pair<ld, ld>>lines;
		lines.emplace_back(0, 0);
		for (int i = 0; i < M; ++i) {
			ld l, r; cin >> l >> r;
			lines.emplace_back(l, (r - l) / W);
		}
		vector<pair<ld, ld>>armonds;
		for (int i = 0; i < N; ++i) {
			ld x, y; cin >> x >> y;
			armonds.emplace_back(x, y);
		}
		vector<pair<int, ld>>areas(M);
		{
			ld asum = 0;
			for (int i = 0; i < M; ++i) {
				ld sum= (2 * lines[i + 1].first + W*lines[i + 1].second)*W / 2;
				areas[i].second = sum - asum;
				asum = sum;
			
			}
		}
		getnum(0, M, armonds, lines, areas);
		int l = 0;
		int r = 0;
		ld needarea = W*H - S + eps;
		ld sum = 0;
		int num = 0;
		int ans = 0;
		bool flag = true;
		while (1) {
			while (sum < needarea) {
				ans = max(ans, num);
				if (r == M) {
					flag = false;
					break;
				}
				else {
					sum += areas[r].second;
					num += areas[r].first;
				}
				r++;
			}
			if (!flag)break;
			while (sum > needarea) {
				sum -= areas[l].second;
				num -= areas[l].first;
				l++;
			}
		}
		cout << N-ans << endl;

	}
	return 0;
}
accuracy: 1
time_ms: 580
memory_kb: 7848
final_rank: 19

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

int n,m,w,h,S;

struct Line{
  double a;
  double b;
  double l;
  double r;

  double gety(double x){
    return a*x+b;
  }
};
struct Point{
  double x;
  double y;

  bool operator < (const Point &a)const{
    return y < a.y;
  }
};


vector <Line> lr;
vector <Point> ar;

int main(){

  while(cin>>n>>m>>w>>h>>S, n|m|w|h|S){
    m += 2;
    lr.clear();
    lr = vector<Line>(m);
    ar.clear();
    ar = vector<Point>(n);
    lr[0].l = lr[0].b = lr[0].a = lr[0].r = 0;

    for(int i = 1; i < m-1; i++){
      double l,r;
      cin>>l>>r;
      lr[i].a = (r-l)/(double)w;
      lr[i].b = l;
      lr[i].l = l;
      lr[i].r = r;
    }
    lr[m-1].l = lr[m-1].b = lr[m-1].r = h;
    lr[m-1].a = 0;
    for(int i = 0; i < n; i++){
      double x, y; cin >> x >> y;
      ar[i].x = x; ar[i].y = y;
    }
    sort(ar.begin(), ar.end());
    vector< pair<int, double> > area(m-1, make_pair(0, 0));

    for(int i = 0; i < n; i++){
      int l = 0, r = m;
      while(l + 1 < r){
        int mid = (l+r)/2;
        if(ar[i].y >= lr[mid].gety(ar[i].x)){
          l = mid;
        }else{
          r = mid;
        }
      }
      area[l].first++;
    }
    for(int i = 0; i < m-1; i++){
      area[i].second = (lr[i+1].l - lr[i].l + lr[i+1].r - lr[i].r)*w/2.0;
    }

    /*
    for(int i = 0; i < area.size(); i++){
      cout << i+1 << ". " << area[i].first << " amds, " << area[i].second << " sqs" << endl;
    }
    */

    vector<double> areasum(area.size()+1, 0);
    vector<int> amsum(area.size()+1, 0);
    double totalarea = h*w;
    for(size_t i = 1; i < areasum.size(); i++){
      areasum[i] += areasum[i-1] + area[i-1].second;
    }
    for(size_t i = 1; i < amsum.size(); i++){
      amsum[i] += amsum[i-1] + area[i-1].first;
    }


    int ans =0;
    for(size_t bottom = 0; bottom < area.size(); bottom++){
      int l = bottom, r = amsum.size();
      while(l+1 < r){
        int mid = (l+r)/2;
        if(areasum[mid] - areasum[bottom] > totalarea - S){
          r = mid;
        }else{
          l = mid;
        }
      }
      ans = max(ans, amsum[l] - amsum[bottom]);
    }
    cout << n - ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 670
memory_kb: 3772
final_rank: 12

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

using namespace std;

#define EPS (1e-8)
#define INF 101010

struct Point {
    double x, y;
    
    Point () {}
    Point (double x, double y) : x(x), y(y) {}

    Point operator - (const Point &p) const {
        return Point(x - p.x, y - p.y);
    }
};

double cross(const Point &a, const Point &b)
{
    return a.x * b.y - a.y * b.x;
}

int ccw(const Point &p0, const Point &p1, const Point &p2)
{
    Point a = p1 - p0, b = p2 - p0;
    if (cross(a, b) > EPS)  return -1; // COUNTER CLOCK WISE
    return +0;
}

#define next(G,i) (G[(i+1)%G.size()])

double get_area(double l, double r, int W)
{
    vector<Point> pg(4);
    pg[0] = Point(0, 0);
    pg[1] = Point(W, 0);
    pg[2] = Point(W, r);
    pg[3] = Point(0, l);
    
    double res = 0;
    for (int i = 0; i < (int)pg.size(); i++) {
	res += cross(pg[i], next(pg, i));
    }
    return abs(res)/2.0;
}


int main()
{
    int N, M, W, H, S;
    while (cin >> N >> M >> W >> H >> S, N) {
        vector<double> l(M+1), r(M+1);
        l[0] = r[0] = 0;
        
        vector<int> s(M+1, 0);
        for (int i = 1; i <= M; i++) {
            scanf("%lf %lf", &l[i], &r[i]);
            s[i] = get_area(l[i], r[i], W);
        }        

        vector<int> choco(M+1, 0);
        
        Point p;
        for (int i = 0; i < N; i++) {
            scanf("%lf %lf", &p.x, &p.y);
            int lb = 0, ub = M+1;
            while (ub - lb > 1) {
                int mid = (lb + ub) / 2;
                if (ccw(Point(0, l[mid]), Point(W, r[mid]), p) == -1) {
                    lb = mid;
                } else {
                    ub = mid;
                }
            }
            choco[ub]++;
        }

        for (int i = 1; i <= M; i++) {
            choco[i] += choco[i-1];
        }
        int res = INF;
        for (int i = 0; i <= M; i++) {
            int lb = i, ub = M+1;
            int ns = s[i];
            while (ub - lb > 1) {
                int mid = (lb + ub) / 2;
                if (ns + (s[M] - s[mid]) < S) {
                    ub = mid;
                } else {
                    lb = mid;
                }
            }

            if (ns + (s[M] - s[lb]) >= S) {
                res = min(res, choco[M] - (choco[lb] - choco[i]));
            }
        }
        cout << res << endl;
    }        
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 3728
final_rank: 4

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

using namespace std;

#define EPS (1e-8)
#define INF 101010

struct Point {
    double x, y;
    
    Point () {}
    Point (double x, double y) : x(x), y(y) {}

    Point operator - (const Point &p) const {
        return Point(x - p.x, y - p.y);
    }
};

double cross(const Point &a, const Point &b)
{
    return a.x * b.y - a.y * b.x;
}

int ccw(const Point &p0, const Point &p1, const Point &p2)
{
    Point a = p1 - p0, b = p2 - p0;
    if (cross(a, b) > EPS)  return -1; // COUNTER CLOCK WISE
    return +0;
}

#define next(G,i) (G[(i+1)%G.size()])

double get_area(double l, double r, int W)
{
    vector<Point> pg(4);
    pg[0] = Point(0, 0);
    pg[1] = Point(W, 0);
    pg[2] = Point(W, r);
    pg[3] = Point(0, l);
    
    double res = 0;
    for (int i = 0; i < (int)pg.size(); i++) {
	res += cross(pg[i], next(pg, i));
    }
    return abs(res)/2.0;
}


int main()
{
    int N, M, W, H, S;
    while (cin >> N >> M >> W >> H >> S, N) {
        vector<double> l(M+1), r(M+1);
        l[0] = r[0] = 0;
        
        vector<int> s(M+1, 0);
        for (int i = 1; i <= M; i++) {
            cin >> l[i] >> r[i];
            s[i] = get_area(l[i], r[i], W);
        }        

        vector<int> choco(M+1, 0);
        
        Point p;
        for (int i = 0; i < N; i++) {
            cin >> p.x >> p.y;
            int lb = 0, ub = M+1;
            while (ub - lb > 1) {
                int mid = (lb + ub) / 2;
                if (ccw(Point(0, l[mid]), Point(W, r[mid]), p) == -1) {
                    lb = mid;
                } else {
                    ub = mid;
                }
            }
            choco[ub]++;
        }

        for (int i = 1; i <= M; i++) {
            choco[i] += choco[i-1];
        }
        int res = INF;
        for (int i = 0; i <= M; i++) {
            int lb = i, ub = M+1;
            int ns = s[i];
            while (ub - lb > 1) {
                int mid = (lb + ub) / 2;
                if (ns + (s[M] - s[mid]) < S) {
                    ub = mid;
                } else {
                    lb = mid;
                }
            }

            if (ns + (s[M] - s[lb]) >= S) {
                res = min(res, choco[M] - (choco[lb] - choco[i]));
            }
        }
        cout << res << endl;
    }        
    return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 3684
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define f first
#define s second
#define x real()
#define y imag()
using namespace std;
typedef complex <double> point;
typedef pair <int,int> P;
int n,m,w,h,S;
point L[30001][2];
point A[30001];
long long arm[30001];
 
bool ccw(point a,point b,point c){
  b-=a,c-=a;
  c*=conj(b);
  return (c.y>0);
}
 
void mk_arm(){
  memset(arm,0,sizeof(arm));
  for(int i=0;i<n;i++){
    int low=0,mid,up=m+1;
    while(low<up){
      mid=(low+up)/2;
      if(!ccw(L[mid][0],L[mid][1],A[i]))up=mid;
      else low=mid+1;
    }
    arm[low]++;
  }
   
  for(int i=1;i<=m;i++)arm[i]+=arm[i-1];
  arm[m+1]=n;
}
 
int solve(){
  long long res=0;
  for(int i=0;i<m;i++){
    int low=i,mid,up=m+1;
    while(low<up){
      mid=(low+up)/2;
      double sss=(L[mid][0].y-L[i][0].y+L[mid][1].y-L[i][1].y)*w/2.0;
      if(w*h-(sss)<S) up=mid;
      else low=mid+1; 
    }
    res=max(res,(arm[low-1]-arm[i]));
  }
  assert(n-res>=0);
  return n-res;
}
 
int main(){
   
  while(1){
    cin>>n>>m>>w>>h>>S;
    if(!n&&!m&&!w&&!h&&!S)break;
     
    L[0][0]=point(0,0),L[0][1]=point(w,0);
    for(int i=1,a,b;i<=m;i++){
      cin>>a>>b;
      L[i][0]=point(0,a);
      L[i][1]=point(w,b);
    }
 
    double a,b;
    for(int i=0;i<n;i++)cin>>a>>b,A[i]=point(a,b);
    mk_arm();
    cout << solve()<<endl;
  }
   
  return 0;
}
accuracy: 1
time_ms: 630
memory_kb: 2888
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define f first
#define s second
#define x real()
#define y imag()
using namespace std;
typedef complex <double> point;
int n,m,w,h,S;
point L[30001][2];
point A[30001];
int arm[30001];
 
bool ccw(point a,point b,point c){
  b-=a,c-=a;
  c*=conj(b); 
   return (c.y>0);
}
 
void mk_arm(){
  memset(arm,0,sizeof(arm));
  for(int i=0;i<n;i++){
    int low=0,mid,up=m+1;
    while(low<up){
      mid=(low+up)/2;
      if(!ccw(L[mid][0],L[mid][1],A[i])) up=mid;
      else low=mid+1;
    }
    arm[low]++;
  }
  for(int i=1;i<=m;i++)arm[i]+=arm[i-1];
}
 
int solve(){
  int res=0;
  for(int i=0;i<m;i++){
    int low=i,mid,up=m+1;
    while(low<up){
      mid=(low+up)/2;
      double sss=((L[mid][0].y-L[i][0].y)+(L[mid][1].y-L[i][1].y))*w/2.0;
      if(w*h-(sss)<S) up=mid;
      else low=mid+1; 
    }
    res=max(res,(arm[low-1]-arm[i]));
  }
  return n-res;
}
 
int main(){
  while(1){
    cin>>n>>m>>w>>h>>S;
    if(!n&&!m&&!w&&!h&&!S)break;
    L[0][0]=point(0,0);
    L[0][1]=point(w,0);
    for(int i=1,a,b;i<=m;i++){
      cin>>a>>b;
      L[i][0]=point(0,a);
      L[i][1]=point(w,b);
    }
 
    double a,b;
    for(int i=0;i<n;i++)cin>>a>>b,A[i]=point(a,b);
    mk_arm();
    cout << solve()<<endl;
  }
   
  return 0;
}
accuracy: 1
time_ms: 630
memory_kb: 2772
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define f first
#define s second
#define x real()
#define y imag()
using namespace std;
typedef complex <double> point;
int n,m,w,h,S;
point L[30001][2];
point A[30001];
int arm[30001];
 
bool ccw(point a,point b,point c){
  b-=a,c-=a;
  //  c*=b;
  
  return (b.x*c.y-b.y*c.x>0);
}
 
void mk_arm(){
  memset(arm,0,sizeof(arm));
  for(int i=0;i<n;i++){
    int low=0,mid,up=m+1;
    while(low<up){
      mid=(low+up)/2;
      if(!ccw(L[mid][0],L[mid][1],A[i])) up=mid;
      else low=mid+1;
    }
    arm[low]++;
  }
  for(int i=1;i<=m;i++)arm[i]+=arm[i-1];
}
 
int solve(){
  int res=0;
  for(int i=0;i<m;i++){
    int low=i,mid,up=m+1;
    while(low<up){
      mid=(low+up)/2;
      double sss=((L[mid][0].y-L[i][0].y)+(L[mid][1].y-L[i][1].y))*w/2.0;
      if(w*h-(sss)<S) up=mid;
      else low=mid+1; 
    }
    res=max(res,(arm[low-1]-arm[i]));
  }
  return n-res;
}
 
int main(){
  while(1){
    cin>>n>>m>>w>>h>>S;
    if(!n&&!m&&!w&&!h&&!S)break;
    L[0][0]=point(0,0);
    L[0][1]=point(w,0);
    for(int i=1,a,b;i<=m;i++){
      cin>>a>>b;
      L[i][0]=point(0,a);
      L[i][1]=point(w,b);
    }
 
    double a,b;
    for(int i=0;i<n;i++)cin>>a>>b,A[i]=point(a,b);
    mk_arm();
    cout << solve()<<endl;
  }
   
  return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 2764
final_rank: 1