Problem:
Escape from the Hell
One day, Buddha looked into the hell and found an office worker. He did evil, such as enforcing hard work on his subordinates. However, he made only one good in his life. He refused an unreasonable request from his customer to save the lives of his subordinates. Buddha thought that, as the reward of the good, the office worker should have had a chance to escape from the hell. Buddha took a spider silk and put down to the hell.
The office worker climbed up with the spider silk, however the length of the way $L$ meters was too long to escape one day. He had $N$ energy drinks and drunk one of them each day. The day he drunk the i-th energy drink he could climb $A_i$ meters in the daytime and after that slided down $B_i$ meters in the night. If he could reach at the height greater than or equal to the $L$ meters in the daytime, he could escape without sliding down. After the $N$ days the silk would be cut.
He realized that other sinners climbed the silk in the night. They climbed $C_i$ meters in the $i$-th night without sliding down in the daytime. If they catched up with the office worker, they should have conflicted and the silk would be cut. Therefore he needed to escape before other sinners catched him. Your task is to write a program computing the best order of energy drink and output the earliest day which he could escape. If he could not escape, your program should output -1.
Input
The input consists of a single test case.
$N$ $L$
$A_1$ $B_1$
$A_2$ $B_2$
...
$A_N$ $B_N$
$C_1$
$C_2$
...
$C_N$
The first line contains two integers $N$ ($1 \leq N \leq 10^5$) and $L$ ($1 \leq L \leq 10^9$), which mean the number of energy drinks and the length of the spider silk respectively. The following $N$ lines show the information of the drinks: the $i$-th of them indicates the $i$-th energy drink, he climbed up $A_i$ ($1 \leq A_i \leq 10^9$) meters and slided down $B_i$ ($1 \leq B_i \leq 10^9$) meters. Next $N$ lines show how far other sinners climbed: the $i$-th of them contains an integer $C_i$ ($1 \leq C_i \leq 10^9$), which means they climbed up $C_i$ meters in the $i$-th day.
Output
Print the earliest day which he could escape. If he could not escape, print -1 instead.
Sample Input 1
3 9
6 3
5 2
3 1
2
2
2
Output for the Sample Input 1
2
Sample Input 2
5 20
3 2
4 2
6 3
8 4
10 5
4
2
3
4
5
Output for the Sample Input 2
-1
Sample Input 3
5 20
6 5
7 3
10 3
10 14
4 7
2
5
3
9
2
Output for the Sample Input 3
3
Sample Input 4
4 12
8 4
6 4
2 1
2 1
1
1
4
4
Output for the Sample Input 4
-1

Submitted solutions:

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

using namespace std;

#define si(a) scanf("%d",&a)
#define f first
#define s second
#define mp(a,b) make_pair(a,b)
#define MAX 100005
#define INF 1LL<<50
typedef pair <int, int> Pii;

struct Less {
    bool operator () (Pii a, Pii b) {
        if ((a.f - a.s) == (b.f - b.s)) return a.f<b.f;
        return (a.f-a.s)>(b.f-b.s);
    }
}LL;

vector<pair<long long,long long> > all;
int n,L,C[MAX];
long long cumall[MAX],cumC[MAX],ttt[MAX];
bool allright[MAX];

bool f(int x)
{
    x--;
    if(!x){
        for(int i=0;i<n;i++)
            if(all[i].f>=L)
                return true;
        return false;
    }
    int i;
    ttt[x+1]=INF;
    for(i=x;i>0;i--)
        ttt[i]=min(ttt[i+1],cumall[i]-cumC[i-1]);
    long long mx=0;
    for(i=0;i<x;i++){
        if(i && !allright[i-1])
            continue;
        long long nowmin=ttt[i+1];
        nowmin-=(all[i].f-all[i].s);
        if(nowmin<=0)
            continue;
        mx=max(mx,cumall[x]-(all[i].f-all[i].s)+all[i].f);
    }
    if(allright[x-1]){
        for(i=x;i<n;i++)
            mx=max(mx,cumall[x-1]+all[i].f);
    }
    return mx>=L;
}

int main()
{
    //freopen("input.txt","r",stdin);
    int N,i;
    long long mx=0;
    si(N);si(L);
    for(i=0;i<N;i++){
        long long a,b;
        scanf("%lld%lld",&a,&b);
        if(a<b){
            mx=max(mx,a);
            continue;
        }
        all.push_back(mp(a,b));
        n++;
    }
    for(i=0;i<n;i++)si(C[i]);
    sort(all.begin(),all.end(),LL);
    cumall[0]=all[0].f-all[0].s;
    cumC[0]=C[0];
    allright[0]=(cumall[0]>cumC[0]);
    for(i=1;i<n;i++){
        cumall[i]=cumall[i-1]+(all[i].f-all[i].s);
        cumC[i]=cumC[i-1]+C[i];
        allright[i]=(cumall[i]>cumC[i]);
    }
    long long ans=INF;
    if(mx){
        if(mx>=L)ans=1;
        else{
            for(i=0;i<n;i++){
                if(!allright[i])
                    break;
                if(cumall[i]+mx>=L){
                    ans=i+2;
                    break;
                }
            }
        }
    }
    int l=0,r=n;
    if(f(r)){
        while(r-l>1){
            int mid=(l+r)>>1;
            if(f(mid))r=mid;
            else l=mid;
        }
        ans=min(ans,(long long)r);
    }
    if(ans==INF)printf("-1\n");
    else
        printf("%lld\n",ans);
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 7604
final_rank: 1

code_snippet: //
/*
ID: kfoozmi1
LANG: C++
TASK:
*/
#include <bits/stdc++.h>
using namespace std;

#ifdef kfoozminus
#define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0)

void faltu() {
	cerr << endl;
}

template <typename T>
void faltu(T a[], int n) {
	for(int i = 0; i < n; ++i) cerr << a[i] << ' ';
	cerr << endl;
}

template <typename First, typename ... hello>
void faltu(First arg, const hello&... rest) {
	cerr << arg << ' ';
	faltu(rest...);
}
#else
#define dbg(args...)
#endif

#define PB push_back
#define F first
#define S second
#define MP make_pair
#define SQR(a) ((a) * (a))
#define vsort(v) sort(v.begin(), v.end())
#define memset(a, b) memset(a, b, sizeof a)
#define PQ priority_queue
#define PI acos(-1)
#define EPS 1e-9

#define B1 43
#define B2 43

#define MOD1 1000000007
#define MOD2 1000000009
#define MOD  1000000007

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

//int dx[] = {0, 0, +1, -1};
//int dy[] = {+1, -1, 0, 0};
//int dx[] = {+1, 0, -1, 0, +1, +1, -1, -1};
//int dy[] = {0, +1, 0, -1, +1, -1, +1, -1};

inline bool checkBit(ll n, int i) { return n & (1LL << i); }
inline ll setBit(ll n, int i) { return n | (1LL << i); }
inline ll resetBit(ll n, int i) { return n & (~ (1LL << i)); }
inline bool EQ(double a, double b) { return fabs(a-b) < EPS; }
inline double dist(double ix, double iy, double jx, double jy) { return sqrt(SQR(ix - jx) + SQR(iy - jy)); }

#define PMX 1000000

int marked[PMX/64+2];

#define mark(x) marked[x>>6] |= (1<<((x&63)>>1))
#define check(x) (marked[x>>6] & (1<<((x&63)>>1)))

bool isPrime(int x)
{
    return (x>1) && ((x==2) || ((x&1) && (!(check(x)))));
}

void seive(int n)
{
    int i, j;
    for(i=3; i*i<=n; i+=2)
    {
        if(!check(i))
        {
            for(j=i*i; j<=n; j+=i<<1)
            {
                mark(j);
            }
        }
    }
}

ll bigMod(ll a, ll b)
{
	ll r = 1;
	while(b) {
		if(b & 1) (r *= a) %= MOD;
		b >>= 1;
		(a *= a) %= MOD;
	}
	return r;
}

ll add(ll a, ll b)
{
	ll ret = a + b;
	if(ret >= MOD) ret -= MOD;
	return ret;
}

ll sub(ll a, ll b)
{
	ll ret = a - b;
	if(ret < 0) ret += MOD;
	return ret;
}

#define INF 100000000
#define MX 100007

int t[4 * MX], in[MX], shoja[MX], a[MX], b[MX], c[MX];
vector< pii > v;

void update(int nd, int tl, int tr, int pos, int val)
{
	if(tl == tr) {

		t[nd] = val;
		return ;
	}

	int tm = (tl + tr) >> 1;
	int lc = nd << 1;
	int rc = lc | 1;

	if(pos <= tm) update(lc, tl, tm, pos, val);
	else update(rc, tm + 1, tr, pos, val);

	t[nd] = min(t[lc], t[rc]);
}

int query(int nd, int tl, int tr, int l, int r)
{
	if(tl >= l && tr <= r) return t[nd];

	int tm = (tl + tr) >> 1;
	int lc = nd << 1;
	int rc = lc | 1;

	if(r <= tm) return query(lc, tl, tm, l, r);
	else if(l > tm) return query(rc, tm + 1, tr, l, r);
	else return min(query(lc, tl, tm, l, r), query(rc, tm + 1, tr, l, r));
}

int main()
{
#ifdef kfoozminus
	//freopen("in", "r", stdin);
	//freopen("out", "w", stdout);
#endif
	int L, _L, i, mn, mx, mid, p, n, midd, day;

	scanf("%d %d", &n, &L);
	for(i = 1; i <= n; i ++) {

		scanf("%d %d", &a[i], &b[i]);
		if(a[i] > b[i]) v.PB({ a[i] - b[i], i} );
		else in[i] = -1;
	}
	vsort(v);
	reverse(v.begin(), v.end());
	int sz = v.size();
	for(i = 0; i < sz; i ++) in[ v[i].S ] = i;
	for(i = 1; i <= n; i ++) {
		
		scanf("%d", &c[i]);
		c[i] += c[i - 1];
	}
	for(i = 1; i < sz; i ++) v[i].F += v[i - 1].F;

	if(sz) shoja[0] = v[0].F - c[1];
	for(i = 1; i < sz; i ++) {

		shoja[i] = min(shoja[i - 1], v[i].F - c[i + 1]);
		update(1, 0, sz - 1, i, v[i].F - c[i]);
		dbg(i, v[i].F - c[i]);
	}
	day = INF;
	for(i = 1; i <= n; i ++) {

		_L = L - a[i];
		if(_L <= 0) {
			day = 1;
			break;
		}
		if(in[i] == -1) {
			if(sz < 1) continue;
			mn = 0;
			mx = sz - 1;
			while(mn < mx) {

				mid = (mn + mx) >> 1;
				if(v[mid].F < _L) mn = mid + 1;
				else mx = mid;
			}
			if(v[mn].F < _L) continue;
			if(shoja[mn] > 0) day = min(day, mn + 2);
			dbg(i, mn + 1);
		}
		else {
			if(sz <= 1) continue;
			mn = 0;
			mx = sz - 2;
			while(mn < mx) {

				mid = (mn + mx) >> 1;
				if(mid >= in[i]) midd = mid + 1;
				else midd = mid;
				if(v[midd].F - (mid >= in[i]) * (a[i] - b[i]) < _L) mn = mid + 1;
				else mx = mid;
			}
			if(v[mn + (mn >= in[i])].F - (mn >= in[i]) * (a[i] - b[i]) < _L) continue;
			mn += (mn >= in[i]);

			if(mn < in[i]) {
				if(shoja[mn] > 0) day = min(day, mn + 2);
			}
			else {
				p = query(1, 0, sz - 1, in[i] + 1, mn);
				if((shoja[ in[i] - 1] > 0) &&(p - (a[i] - b[i]) > 0)) day = min(day, mn + 1);
			}
		}
	}
	printf("%d\n", day == INF ? -1: day);
        return 0;
}
accuracy: 0.10416666666666667
time_ms: 10
memory_kb: 4868
final_rank: 20

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

#define rep(i,n) for(i=1;i<=n;i++)
#define Rep(i,n) for(i=0;i<n;i++)

#define mem(ara,val) memset(ara,val,sizeof(ara))
#define pb(x) push_back(x)
#define sz(x) x.size()

#define INF 1000000000000000000ll
#define Max 200005
#define mod 1000000007

#define si(x) scanf("%d",&x)
#define sii(x,y) scanf("%d %d",&x,&y)
#define siii(x,y,z) scanf("%d %d %d",&x,&y,&z)

#define sl(x) scanf("%lld",&x)
#define sll(x,y) scanf("%lld %lld",&x,&y)
#define slll(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)

#define FI freopen("in.txt","r",stdin)

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;

struct info
{
    LL h,d;
    info() {}
    info(LL _h,LL _d) {
        h = _h;
        d = _d;
    }
    bool operator < (const info & p) const
    {
        if(d == p.d)return h < p.h;
        else return d > p.d;
    }
};
info ara[Max];
LL n,need[Max],L;

/// brute
LL brute()
{
    LL i,mn = INF;
    for(LL flag=1;flag<=n;flag++)
    {
        LL tot = 0,cnt = 0;
        LL reach = L - ara[flag].h;
        LL done = 0;

        if(reach <= 0)
        {
            mn = min(mn,1ll);
            continue;
        }

        rep(i,n)
        {
            if(i == flag)continue;
            cnt++;
            tot += ara[i].d;
            if(tot < need[cnt])break;
            if(tot >= reach)
            {
                done = 1;
                break;
            }
        }
        if(done)
        {
            mn = min(mn,cnt+1);
        }
    }
    return mn;
}
///brute




LL afford[Max],cum[Max],good,sat;
LL tree[4*Max];

void init(LL ind,LL b,LL e)
{
    if(b == e)
    {
        tree[ind] = afford[b];
        return;
    }
    LL mid = (b + e) / 2,l = 2 * ind,r = l + 1;
    init(l,b,mid);
    init(r,mid+1,e);
    tree[ind] = min(tree[l],tree[r]);
}

LL Q(LL ind,LL b,LL e,LL i,LL j)
{
    if(i > j)return INF;
    if(b == i && e == j)return tree[ind];
    LL mid = (b + e) / 2,l = 2 * ind,r = l + 1;
    return min( Q(l,b,mid,i,min(mid,j)) , Q(r,mid+1,e,max(mid+1,i),j) );
}

LL bin(LL x)
{
    LL low = 1,high = sat,mid,ans = -1;
    while( low <= high )
    {
        mid = (low + high) / 2;
        if(cum[mid] >= x)
        {
            ans = mid;
            high = mid - 1;
        }
        else low = mid + 1;
    }
    return ans;
}

LL F()
{
    LL i,f = 0;
    rep(i,n)
    {
        if(ara[i].d <= 0)break;
        good = i;
        cum[i] = cum[i-1] + ara[i].d;
        afford[i] = cum[i] - need[i-1];
        if(!f)
        {
            sat = i;
            if(cum[i] < need[i])f = 1;
        }
    }
    if(sat)init(1,1,sat);

    LL ret = INF;
    rep(i,sat)
    {
        LL delta = ara[i].d;
        LL jump = ara[i].h;
        LL pos = bin( L - jump + delta );
        if( pos == -1 )continue;
        LL rmq = INF;
        if(sat)rmq = Q(1,1,sat,i+1,pos);
        if(rmq < delta)continue;
        //if(i == 5)printf("pos %lld rmq %lld delta %lld\n",pos,rmq,delta);
        LL day = pos;
        if(pos < i)day++;
        //if(day == 1)printf("i %lld\n",i);
        ret = min(ret,day);
    }

    for(i=sat+1;i<=n;i++)
    {
        LL jump = ara[i].h;
        LL pos = bin( L - jump );
        if(pos == -1)continue;
        LL day = pos + 1;
        ret = min(ret,day);
    }

    return ret;
}

int main()
{

    //srand( time(0) );
    //FI;
    LL i,x,y;
    sll(n,L);
    rep(i,n)
    {
        sll(x,y);
        ara[i] = info(x,x-y);
    }
    need[0] = 1;
    rep(i,n)
    {
        sl(x);
        need[i] = need[i-1] + x;
    }

    /*n = 10000;
    L = rand() % 10000 + 1;
    rep(i,n)
    {
        x = rand() % 30 + 1;
        y = rand() % 60 + 1;
        ara[i] = info(x,x-y);
    }

    rep(i,n)
    {
        x = rand() % 5 + 1;
        need[i] = need[i-1] + x;
    }*/

    sort(ara+1,ara+n+1);

    LL ret = F();
    if(ret == INF)ret = -1;
    printf("%lld\n",ret);
    //printf("brute %lld\n",brute());
    //printf("my %lld\n",F());
    return 0;
}
accuracy: 0.8333333333333334
time_ms: 30
memory_kb: 13936
final_rank: 13

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

using namespace std;

#define rep(i,n) for(i = 0; i<n; i++)
#define repl(i,n) for(i = 1; i<=n; i++)

#define sz(x)   (int)x.size()
#define pb      push_back
#define all(x)  x.begin(), x.end()
#define uu      first
#define vv  second
#define mem(x,y) memset(x,y,sizeof(x))
#define sdi(x) scanf("%d",&x)
#define sdii(x,y) scanf("%d %d",&x,&y)
#define sdiii(x,y,z)  scanf("%d %d %d",&x,&y,&z)
#define sdl(x) scanf("%lld",&x)
#define sdll(x,y) scanf("%lld %lld",&x,&y)
#define sdlll(x,y,z)  scanf("%lld %lld %lld",&x,&y,&z)
#define sds(x) scanf("%s",s);
#define pfi(x) printf("%d\n",x)
#define pfii(x,y) printf("%d %d\n",x,y)
#define pfiii(x,y,z) printf("%d %d %d\n",x,y,z)
#define pfl(x) printf("%lld\n",x)
#define pfll(x,y) printf("%lld %lld\n",x,y)
#define pflll(x,y,z) printf("%lld %lld %lld\n",x,y,z)

#define eps 1e-9
//#define OK  cerr<< "OK" << '\n'
//#define DB(x) cerr << #x " = " << x << '\n'

#define FRE(i,a,b) for(i = a; i<=b; i++)
#define FRL(i,a,b) for(i = a; i<b; i++)
#define un(x) x.erase(unique(all(x)),x.end())
#define sf(x) scanf("%d",&x)
#define sff(x,y) scanf("%d %d",&x,&y)
#define sfff(x,y,z)  scanf("%d %d %d",&x,&y,&z)
#define sl(x) scanf("%lld",&x)
#define sll(x,y) scanf("%lld %lld",&x,&y)
#define slll(x,y,z)  scanf("%lld %lld %lld",&x,&y,&z)
#define D(x)        cerr << #x " = " << x << '\n'
#define DBG         cerr << "Hi" << '\n'
#define PI          acose(-1.00)
#define xx          first
#define yy          second

typedef double db;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
typedef pair<long long,long long> pll;

inline int setBit(int N, int pos) { return N=N|(1<<pos);}
inline int resetBit(int N, int pos) {return N=N &~(1<<pos);}
inline bool checkBit(int N, int pos) {return (bool) (N & (1<<pos));}


//int fx[] = {+0, +0, +1, -1, +1, -1, +1};
//int fy[] = {-1, +1, +0, +0, +1, -1, -1};


const int MAX = 100005;
int n, ub;
LL c[MAX], cumDelta[MAX], cumC[MAX], tree[MAX*4], l;
struct data {
    int a, b;
    inline bool operator < (const data &p) const {
        return ((a-b) > (p.a-p.b));
    }
} arr[MAX];

void init(int node, int beg, int endd) {
    if(beg == endd) {
        tree[node] = cumDelta[beg] - cumC[beg];
        return;
    }

    int left = node << 1;
    int right = left + 1;
    int mid = (beg+endd) >> 1;

    init(left, beg, mid);
    init(right, mid+1, endd);

    tree[node] = min(tree[left], tree[right]);
}

void update(int node, int beg, int endd, int x, LL val) {
    if(beg == endd) {
        tree[node] += val;
        return;
    }

    int left = node << 1;
    int right = left + 1;
    int mid = (beg+endd) >> 1;

    if(x <= mid) update(left, beg, mid, x, val);
    else update(right, mid+1, endd, x, val);

    tree[node] = min(tree[left], tree[right]);
}

LL query(int node, int beg, int endd, int x, int y) {
    if(x > y) return LLONG_MAX;
    if(beg == x && endd == y) return tree[node];

    int left = node << 1;
    int right = left + 1;
    int mid = (beg+endd) >> 1;

    LL l = query(left, beg, mid, x, min(y, mid));
    LL r = query(right, mid+1, endd, max(x, mid+1), y);

    return min(l, r);
}

inline int bs(int idx) {
    int low=1, high=ub, mid, ret=n+5;
    while(low <= high) {
        mid = (low+high) >> 1;
        LL x = cumDelta[mid];
        if(mid >= idx) x -= (arr[idx].a - arr[idx].b);
        if(x >= l - arr[idx].a) {
            ret = min(ret, mid);
            high = mid-1;
        }
        else low = mid+1;
    }
    return ret;
}

inline int check(int idx) {
    update(1, 1, n, idx, -cumDelta[idx]);
    if(idx < n) update(1, 1, n, idx, cumDelta[idx+1]);
    if(arr[idx].a >= l) return 1;
    int here = bs(idx);
//    DB(here);
    if(here > n) return here;
    if(query(1, 1, n, 1, here) >= 0ll) {
        if(idx > here) here++;
        return here;
    }
    else return n+5;
}

int solve() {
    int ret = n+5, i;
    for(i=n; i>=1; i--) {
        int x = check(i);
//        DB(x);
        ret = min(ret, x);
    }
    if(ret > n) return -1;
    else return ret;
}

int main() {
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);

    int i;

    sdi(n);
    sdl(l);
    repl(i, n) sdll(arr[i].a, arr[i].b);
    repl(i, n) sdl(c[i]);

    sort(arr+1, arr+1+n);
    ub = 0;
    repl(i, n) {
        if(arr[i].a >= arr[i].b) ub = i;
    }
    repl(i, n) {
        cumDelta[i] = cumDelta[i-1];
        cumDelta[i] += (arr[i].a - arr[i].b);
    }
    repl(i, n) {
        cumC[i] = cumC[i-1];
        cumC[i] += c[i];
    }

//    repl(i, n) pfll(arr[i].a, arr[i].b); puts("----------");
//    repl(i, n) pfl(c[i]);

    init(1, 1, n);
    pfi(solve());

    return 0;
}
accuracy: 0.7291666666666666
time_ms: 40
memory_kb: 9788
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,n) for(i64 i=0; i<i64(n); i++)

struct RMQ{
    i64 N;
    vector<i64> A;
    RMQ(vector<i64> a = {}){
        N = 1; while(N < i64(a.size())) N*=2;
        A.assign(N*2, 1ll<<60);
        rep(i,a.size()) A[N+i] = a[i];
        for(i64 i=N-1; i>=1; i--) A[i] = min(A[i*2], A[i*2+1]);
    }
    i64 query(i64 l, i64 r){
        l += N; r += N;
        i64 res = 1ll << 60;
        while(l < r){
            if(l%2) res = min(res, A[l++]);
            if(r%2) res = min(res, A[--r]);
            l /= 2; r /= 2;
        }
        return res;
    }
};

bool nachia = false;

i64 solve(i64 N, i64 L, vector<pair<i64,i64>> A, vector<i64> C){
    i64 ans = N+1;
    sort(A.rbegin(), A.rend());
    vector<i64> K(N+1); rep(i,N) K[i+1] = K[i] + C[i];

    vector<i64> D(N+1);
    rep(i,N) D[i+1] = D[i] + A[i].first;
    i64 cap_straight = 0;
    while(cap_straight < N && D[cap_straight+1] > K[cap_straight+1]) cap_straight++;

    vector<i64> capdiff(N);
    rep(i,N) capdiff[i] = D[i+1] - K[i];
    auto ds = RMQ(capdiff);

    if(nachia){
        cout << "D = "; for(auto d : D){ cout << d << " "; } cout << endl;
        cout << "cap = "; for(auto d : capdiff){ cout << d << " "; } cout << endl;
    }

    i64 maxDi = max_element(D.begin(), D.end()) - D.begin();

    rep(f,N){
        if(nachia) cout << "f = " << f << endl;
        if(f >= maxDi || D[f] + A[f].second >= L){
            if(nachia) cout << "  case A" << endl;
            if(D[maxDi] + A[f].second < L) continue;
            i64 t = lower_bound(D.begin(), D.begin() + maxDi + 1, L-A[f].second) - D.begin();
            if(cap_straight < t) continue;
            t += 1;
            if(nachia) cout << "  ok t = " << t << endl;
            if(t < ans) ans = t;
            continue;
        }
        if(nachia) cout << "  case B" << endl;
        if(cap_straight < f) continue;
        i64 offset = A[f].second - A[f].first;
        i64 loss = A[f].first;
        if(D[maxDi] + offset < L) continue;
        i64 g = lower_bound(D.begin(), D.begin() + maxDi + 1, L-offset) - D.begin();
        i64 cap = ds.query(f+1, g);
        if(nachia){ cout << "  query : "; for(int i=f+1; i<g; i++){ cout <<capdiff[i] << " "; } cout << endl; }
        if(nachia){ cout << "  offset = " << offset << " , g = " << g << " , cap = " << cap << endl; }
        if(cap <= loss) continue;
        if(g < ans) ans = g;
    }
    
    if(ans == N+1) return -1;
    return ans;
}

i64 naive(i64 N, i64 L, vector<pair<i64,i64>> A, vector<i64> C){
    i64 ans = N+1;
    sort(A.rbegin(), A.rend());
    rep(f,N){
        i64 a = 0, c = 0;
        i64 t = 0;
        rep(j,N) if(j != f){
            if(A[f].second + a >= L) break;
            a += A[j].first;
            c += C[t];
            t++;
            if(a <= c){ t = -1; break; }
        }
        if(t < 0) continue;
        if(A[f].second + a >= L){
            i64 k = t + 1;
            if(k < ans) ans = k;
        }
    }
    return ans > N ? -1 : ans;
}


void testcase(){
    i64 N; cin >> N;
    i64 L; cin >> L;
    vector<pair<i64,i64>> A(N);
    rep(i,N){
        i64 a,b; cin >> a >> b;
        A[i] = { a-b, a };
    }
    vector<i64> C(N); rep(i,N) cin >> C[i];
    i64 ans = solve(N, L, A, C);
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    testcase();
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 13060
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,n) for(i64 i=0; i<i64(n); i++)

struct RMQ{
    i64 N;
    vector<i64> A;
    RMQ(vector<i64> a = {}){
        N = 1; while(N < i64(a.size())) N*=2;
        A.assign(N*2, 1ll<<60);
        rep(i,a.size()) A[N+i] = a[i];
        for(i64 i=N-1; i>=1; i--) A[i] = min(A[i*2], A[i*2+1]);
    }
    i64 query(i64 l, i64 r){
        l += N; r += N;
        i64 res = 1ll << 60;
        while(l < r){
            if(l%2) res = min(res, A[l++]);
            if(r%2) res = min(res, A[--r]);
            l /= 2; r /= 2;
        }
        return res;
    }
};

bool nachia = false;

i64 solve(i64 N, i64 L, vector<pair<i64,i64>> A, vector<i64> C){
    i64 ans = N+1;
    sort(A.rbegin(), A.rend());
    vector<i64> K(N+1); rep(i,N) K[i+1] = K[i] + C[i];

    vector<i64> D(N+1);
    rep(i,N) D[i+1] = D[i] + A[i].first;
    i64 cap_straight = 0;
    while(cap_straight < N && D[cap_straight+1] > K[cap_straight+1]) cap_straight++;

    vector<i64> capdiff(N);
    rep(i,N) capdiff[i] = D[i+1] - K[i];
    auto ds = RMQ(capdiff);

    if(nachia){
        cout << "D = "; for(auto d : D){ cout << d << " "; } cout << endl;
        cout << "cap = "; for(auto d : capdiff){ cout << d << " "; } cout << endl;
    }

    i64 maxDi = max_element(D.begin(), D.end()) - D.begin();

    rep(f,N){
        if(nachia) cout << "f = " << f << endl;
        if(f >= maxDi || D[f] >= L){
            if(nachia) cout << "  case A" << endl;
            i64 t = lower_bound(D.begin(), D.begin() + maxDi + 1, L-A[f].second) - D.begin();
            if(cap_straight < t) continue;
            t += 1;
            if(t < ans) ans = t;
            continue;
        }
        if(nachia) cout << "  case B" << endl;
        if(cap_straight < f) continue;
        i64 offset = A[f].second - A[f].first;
        if(D[maxDi] + offset < L) continue;
        i64 g = lower_bound(D.begin(), D.begin() + maxDi + 1, L-offset) - D.begin();
        i64 cap = ds.query(f, g);
        if(nachia) cout << "  offset = " << offset << " , g = " << g << " , cap = " << cap << endl;
        if(cap < offset) continue;
        if(g < ans) ans = g;
    }
    
    if(ans == N+1) return -1;
    return ans;
}

void testcase(){
    i64 N; cin >> N;
    i64 L; cin >> L;
    vector<pair<i64,i64>> A(N);
    rep(i,N){
        i64 a,b; cin >> a >> b;
        A[i] = { a-b, a };
    }
    vector<i64> C(N); rep(i,N) cin >> C[i];
    i64 ans = solve(N, L, A, C);
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    testcase();
    return 0;
}
accuracy: 0.6041666666666666
time_ms: 20
memory_kb: 12968
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,n) for(i64 i=0; i<i64(n); i++)

struct RMQ{
    i64 N;
    vector<i64> A;
    RMQ(vector<i64> a = {}){
        N = 1; while(N < i64(a.size())) N*=2;
        A.assign(N*2, 1ll<<60);
        rep(i,a.size()) A[N+i] = a[i];
        for(i64 i=N-1; i>=1; i--) A[i] = min(A[i*2], A[i*2+1]);
    }
    i64 query(i64 l, i64 r){
        l += N; r += N;
        i64 res = 1ll << 60;
        while(l < r){
            if(l%2) res = min(res, A[l++]);
            if(r%2) res = min(res, A[--r]);
            l /= 2; r /= 2;
        }
        return res;
    }
};

bool nachia = false;

i64 solve(i64 N, i64 L, vector<pair<i64,i64>> A, vector<i64> C){
    i64 ans = N+1;
    sort(A.rbegin(), A.rend());
    vector<i64> K(N+1); rep(i,N) K[i+1] = K[i] + C[i];

    vector<i64> D(N+1);
    rep(i,N) D[i+1] = D[i] + A[i].first;
    i64 cap_straight = 0;
    while(cap_straight < N && D[cap_straight+1] >= K[cap_straight+1]) cap_straight++;

    vector<i64> capdiff(N);
    rep(i,N) capdiff[i] = D[i+1] - K[i];
    auto ds = RMQ(capdiff);

    if(nachia){
        cout << "D = "; for(auto d : D){ cout << d << " "; } cout << endl;
        cout << "cap = "; for(auto d : capdiff){ cout << d << " "; } cout << endl;
    }

    i64 maxDi = max_element(D.begin(), D.end()) - D.begin();

    rep(f,N){
        if(nachia) cout << "f = " << f << endl;
        if(f >= maxDi || D[f] >= L){
            if(nachia) cout << "  case A" << endl;
            i64 t = lower_bound(D.begin(), D.begin() + maxDi + 1, L-A[f].second) - D.begin();
            if(cap_straight < t) continue;
            t += 1;
            if(t < ans) ans = t;
            continue;
        }
        if(nachia) cout << "  case B" << endl;
        if(cap_straight < f) continue;
        i64 offset = A[f].second - A[f].first;
        if(D[maxDi] + offset < L) continue;
        i64 g = lower_bound(D.begin(), D.begin() + maxDi + 1, L-offset) - D.begin();
        i64 cap = ds.query(f, g);
        if(nachia) cout << "  offset = " << offset << " , g = " << g << " , cap = " << cap << endl;
        if(cap < offset) continue;
        if(g < ans) ans = g;
    }
    
    if(ans == N+1) return -1;
    return ans;
}

void testcase(){
    i64 N; cin >> N;
    i64 L; cin >> L;
    vector<pair<i64,i64>> A(N);
    rep(i,N){
        i64 a,b; cin >> a >> b;
        A[i] = { a-b, a };
    }
    vector<i64> C(N); rep(i,N) cin >> C[i];
    i64 ans = solve(N, L, A, C);
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    testcase();
    return 0;
}
accuracy: 0.6041666666666666
time_ms: 20
memory_kb: 12964
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,n) for(i64 i=0; i<i64(n); i++)

struct RMQ{
    i64 N;
    vector<i64> A;
    RMQ(vector<i64> a = {}){
        N = 1; while(N < i64(a.size())) N*=2;
        A.assign(N*2, 1ll<<60);
        rep(i,a.size()) A[N+i] = a[i];
        for(i64 i=N-1; i>=1; i--) A[i] = min(A[i*2], A[i*2+1]);
    }
    i64 query(i64 l, i64 r){
        l += N; r += N;
        i64 res = 1ll << 60;
        while(l < r){
            if(l%2) res = min(res, A[l++]);
            if(r%2) res = min(res, A[--r]);
            l /= 2; r /= 2;
        }
        return res;
    }
};

bool nachia = false;

i64 solve(i64 N, i64 L, vector<pair<i64,i64>> A, vector<i64> C){
    i64 ans = N+1;
    sort(A.rbegin(), A.rend());
    vector<i64> K(N+1); rep(i,N) K[i+1] = K[i] + C[i];

    vector<i64> D(N+1);
    rep(i,N) D[i+1] = D[i] + A[i].first;
    i64 cap_straight = 0;
    while(cap_straight < N && D[cap_straight+1] >= K[cap_straight]) cap_straight++;

    vector<i64> capdiff(N);
    rep(i,N) capdiff[i] = D[i+1] - K[i];
    auto ds = RMQ(capdiff);

    if(nachia){
        cout << "D = "; for(auto d : D){ cout << d << " "; } cout << endl;
        cout << "cap = "; for(auto d : capdiff){ cout << d << " "; } cout << endl;
    }

    i64 maxDi = max_element(D.begin(), D.end()) - D.begin();

    rep(f,N){
        if(nachia) cout << "f = " << f << endl;
        if(f >= maxDi || D[f] >= L){
            if(nachia) cout << "  case A" << endl;
            i64 t = lower_bound(D.begin(), D.begin() + maxDi + 1, L-A[f].second) - D.begin();
            if(cap_straight < t) continue;
            t += 1;
            if(t < ans) ans = t;
            continue;
        }
        if(nachia) cout << "  case B" << endl;
        if(cap_straight < f) continue;
        i64 offset = A[f].second - A[f].first;
        if(D[maxDi] + offset < L) continue;
        i64 g = lower_bound(D.begin(), D.begin() + maxDi + 1, L-offset) - D.begin();
        i64 cap = ds.query(f, g);
        if(nachia) cout << "  offset = " << offset << " , g = " << g << " , cap = " << cap << endl;
        if(cap < offset) continue;
        if(g < ans) ans = g;
    }
    
    if(ans == N+1) return -1;
    return ans;
}

void testcase(){
    i64 N; cin >> N;
    i64 L; cin >> L;
    vector<pair<i64,i64>> A(N);
    rep(i,N){
        i64 a,b; cin >> a >> b;
        A[i] = { a-b, a };
    }
    vector<i64> C(N); rep(i,N) cin >> C[i];
    i64 ans = solve(N, L, A, C);
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    testcase();
    return 0;
}
accuracy: 0.6041666666666666
time_ms: 20
memory_kb: 13004
final_rank: 17

code_snippet: // AOJ #2785 Escape from the Hell
// 2025.3.14

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = LLONG_MAX;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct Drink { ll a, b; };

int solve(){
    int N = Cin();
    ll L = Cin();

    vector<Drink> dArr(N);
    priority_queue< pair<ll,int> > pqA;
    priority_queue< pair<ll,int> > pqB;

    vector< pair<ll,int> > ord;
    for(int i = 0; i < N; i++){
        dArr[i].a = Cin(), dArr[i].b = Cin();
        ord.push_back({dArr[i].a - dArr[i].b, i});
        pqA.push({dArr[i].a, i});
    }
    vector<ll> C(N);
    for(int i = 0; i < N; i++) C[i] = Cin();

    sort(ord.begin(), ord.end(), [&dArr](auto &p, auto &q) {
        return (p.first == q.first) ? (dArr[p.second].b < dArr[q.second].b) : (p.first > q.first);
    });

    vector<ll> usedDay(N, INF);
    ll myH = 0;
    ll enemyH = 0;
    int delPtr = 0;

    if(!pqA.empty() && pqA.top().first >= L) return 1;

    for(int i = 0; i < N; i++){
        while(!pqA.empty() && usedDay[pqA.top().second] < i) pqA.pop();
        if(!pqA.empty() && myH + pqA.top().first >= L) return i+1;

        int curIdx = ord[i].second;
        ll delta = ord[i].first;
        myH += delta;

        pqB.push({ dArr[curIdx].b, curIdx });

        while(delPtr < i && myH - ord[delPtr].first <= enemyH) delPtr++;

        while(!pqB.empty() && usedDay[pqB.top().second] < delPtr) pqB.pop();

        if(!pqB.empty() && myH + pqB.top().first >= L) return i+1;

        usedDay[curIdx] = i;
        enemyH += C[i];
        if(enemyH >= myH) return -1;
    }
    return -1;
}

int main() {
    Cout(solve());
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 12276
final_rank: 4

code_snippet: // AOJ #2785 Escape from the Hell
// 2025.3.14

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

struct Dr { ll A, B, d; };

struct Seg {
    int n;
    vector<ll> seg;
    Seg(int n): n(n) {
        seg.assign(2*n, 0);
    }
    void build(const vector<ll>& arr) {
        for (int i = 0; i < n; i++) seg[n+i] = arr[i];
        for (int i = n-1; i > 0; i--) seg[i] = max(seg[2*i], seg[2*i+1]);
    }
    ll qry(int l, int r) {
        ll res = 0;
        l += n; r += n;
        while(l <= r){
            if(l % 2 == 1){ res = max(res, seg[l]); l++; }
            if(r % 2 == 0){ res = max(res, seg[r]); r--; }
            l /= 2; r /= 2;
        }
        return res;
    }
};

bool cmp(const Dr &p, const Dr &q){
    if(p.d == q.d) return p.B < q.B;
    return p.d > q.d;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n; ll L;
    cin >> n >> L;
    vector<Dr> v(n);
    for (int i = 0; i < n; i++){
        cin >> v[i].A >> v[i].B;
        v[i].d = v[i].A - v[i].B;
    }
    vector<ll> C(n);
    for (int i = 0; i < n; i++) cin >> C[i];

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

    vector<ll> suf(n);
    suf[n-1] = v[n-1].A;
    for (int i = n-2; i >= 0; i--) suf[i] = max(v[i].A, suf[i+1]);

    vector<ll> arr(n);
    for (int i = 0; i < n; i++) arr[i] = v[i].B;

    Seg segt(n);
    segt.build(arr);

    vector<ll> S(n+1, 0);
    for (int i = 1; i <= n; i++) S[i] = S[i-1] + v[i-1].d;
    vector<ll> M(n+1, 0);
    for (int i = 1; i <= n; i++) M[i] = M[i-1] + C[i-1];

    if(n >= 1 && suf[0] >= L){
        cout << 1 << endl;
        return 0;
    }

    int ans = -1;
    ll mn = LLONG_MAX;
    for (int d = 2; d <= n; d++){
        ll cur = S[d-1] - M[d-1];
        if(cur <= 0) break;
        mn = min(mn, cur);

        if(d-1 < n && S[d-1] + suf[d-1] >= L){
            ans = d;
            break;
        }

        int lo = 0, hi = d-1, pos = d;
        while(lo <= hi){
            int mid = (lo + hi) / 2;
            if(v[mid].d < mn) pos = mid, hi = mid - 1;
            else lo = mid + 1;
        }
        if(pos < d){
            ll cand = segt.qry(pos, d-1);
            if(S[d-1] + cand >= L){
                ans = d;
                break;
            }
        }
    }
    cout << (ans == -1 ? -1 : ans) << endl;
    return 0;
}
accuracy: 0.2916666666666667
time_ms: 20
memory_kb: 10324
final_rank: 18

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<ll,ll>;
using vi = vector<ll>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using ve = vector<vector<int>>;
using vb = vector<bool>;
using vvb = vector<vb>;
#define rep(i,n) for(ll i = 0;i < (ll)n;i++)
#define ALL(x) (x).begin(),(x).end()
#define sz(c) ((ll)(c).size())
#define LB(A,x) (int)(lower_bound(A.begin(),A.end(),x)-A.begin())
#define UB(A,x) (int)(upper_bound(A.begin(),A.end(),x)-A.begin())
// #define MOD 1000000007
#define MOD 998244353
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(int i = 0;i < v.size();i++)os<<v[i]<<(i+1!=v.size()?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T> inline bool chmax(T &a,T b){if(a < b){a = b;return true;}return false;}
template<typename T> inline bool chmin(T &a,T b){if(a > b){a = b;return true;}return false;}
ld dist(ld x1,ld y1,ld x2, ld y2){return sqrtl((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}


int main(){
  
  ios_base::sync_with_stdio(0), cin.tie(0);
  ll n,L;cin >> n >> L;
  vi a(n),b(n);
  rep(i,n)cin >> a[i] >> b[i];
  vi c(n);cin >> c;
  vi idx(n);
  iota(ALL(idx),0);
  sort(ALL(idx),[&](int i,int j){
    return a[i]-b[i] > a[j]-b[j];
  });
  vi ruiC(n+1);
  rep(i,n)ruiC[i+1] = ruiC[i] + c[i];
  vi rui(n+1);
  rep(i,n)rui[i+1] = rui[i] + a[idx[i]] - b[idx[i]];
  int res = MOD;
  ll lst = n;
  rep(i,n)if(ruiC[i+1] >= rui[i+1]){
    lst = i;
    break;
  }
  {
    vi v;
    for(int i = n-1;i >= 0;i--){
      if(a[idx[i]] <= b[idx[i]]){
        v.emplace_back(a[idx[i]]);
        rui.pop_back();ruiC.pop_back();
      }else break;
    }
    n = sz(rui)-1;
    chmin(lst,n);
    for(auto au : v){
      int k = LB(rui,L-au);
      if(k-1 >= lst)continue;
      chmin(res,k+1);
    }
  }
  min_priority_queue<P> que;
  for(int i = n-1;i >= 0;i--){
    int A = a[idx[i]],B = b[idx[i]];
    while(!que.empty()){
      auto [x,y] = que.top();
      if(x <= A-B){
        chmin(lst,y);
        que.pop();
      }else break;
    }
    int k = LB(rui,L-A);
    int g = 0;
    if(k >= i+1){g = 1;
      k = LB(rui,L-A+(A-B));
    }
    if(k-1 < lst)chmin(res,k-g+1);
    que.push({rui[i+1]-ruiC[i],i});
  }
  cout << (res == MOD ? -1 : res) << "\n";
  

  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 9852
final_rank: 2

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<ll,ll>;
using vi = vector<ll>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using ve = vector<vector<int>>;
using vb = vector<bool>;
using vvb = vector<vb>;
#define rep(i,n) for(ll i = 0;i < (ll)n;i++)
#define ALL(x) (x).begin(),(x).end()
#define sz(c) ((ll)(c).size())
#define LB(A,x) (int)(lower_bound(A.begin(),A.end(),x)-A.begin())
#define UB(A,x) (int)(upper_bound(A.begin(),A.end(),x)-A.begin())
// #define MOD 1000000007
#define MOD 998244353
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(int i = 0;i < v.size();i++)os<<v[i]<<(i+1!=v.size()?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T> inline bool chmax(T &a,T b){if(a < b){a = b;return true;}return false;}
template<typename T> inline bool chmin(T &a,T b){if(a > b){a = b;return true;}return false;}
ld dist(ld x1,ld y1,ld x2, ld y2){return sqrtl((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}


int main(){
  
  ios_base::sync_with_stdio(0), cin.tie(0);
  ll n,L;cin >> n >> L;
  vi a(n),b(n);
  rep(i,n)cin >> a[i] >> b[i];
  vi c(n);cin >> c;
  vi idx(n);
  iota(ALL(idx),0);
  sort(ALL(idx),[&](int i,int j){
    return a[i]-b[i] > a[j]-b[j];
  });
  vi ruiC(n+1);
  rep(i,n)ruiC[i+1] = ruiC[i] + c[i];
  vi rui(n+1);
  rep(i,n)rui[i+1] = rui[i] + a[idx[i]] - b[idx[i]];
  int res = MOD;
  {
    vi v;
    for(int i = n-1;i >= 0;i--){
      if(a[idx[i]] <= b[idx[i]]){
        v.emplace_back(a[idx[i]]);
        rui.pop_back();ruiC.pop_back();
      }else break;
    }
    n = sz(rui)-1;
    for(auto au : v){
      int k = LB(rui,L-au);
      if(k-1 > n-1)continue;
      chmin(res,k+1);
    }
  }
  ll lst = n;
  rep(i,n)if(ruiC[i+1] >= rui[i+1]){
    lst = i;
    break;
  }
  min_priority_queue<P> que;
  for(int i = n-1;i >= 0;i--){
    int A = a[idx[i]],B = b[idx[i]];
    while(!que.empty()){
      auto [x,y] = que.top();
      if(x <= A-B){
        chmin(lst,y);
        que.pop();
      }else break;
    }
    int k = LB(rui,L-A);
    int g = 0;
    if(k >= i+1){g = 1;
      k = LB(rui,L-A+(A-B));
    }
    if(k-1 < lst)chmin(res,k-g+1);
    que.push({rui[i+1]-ruiC[i],i});
  }
  cout << (res == MOD ? -1 : res) << "\n";
  

  return 0;
}
accuracy: 0.8333333333333334
time_ms: 30
memory_kb: 9912
final_rank: 12

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<ll,ll>;
using vi = vector<ll>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using ve = vector<vector<int>>;
using vb = vector<bool>;
using vvb = vector<vb>;
#define rep(i,n) for(ll i = 0;i < (ll)n;i++)
#define ALL(x) (x).begin(),(x).end()
#define sz(c) ((ll)(c).size())
#define LB(A,x) (int)(lower_bound(A.begin(),A.end(),x)-A.begin())
#define UB(A,x) (int)(upper_bound(A.begin(),A.end(),x)-A.begin())
// #define MOD 1000000007
#define MOD 998244353
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(int i = 0;i < v.size();i++)os<<v[i]<<(i+1!=v.size()?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T> inline bool chmax(T &a,T b){if(a < b){a = b;return true;}return false;}
template<typename T> inline bool chmin(T &a,T b){if(a > b){a = b;return true;}return false;}
ld dist(ld x1,ld y1,ld x2, ld y2){return sqrtl((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}


int main(){
  
  ios_base::sync_with_stdio(0), cin.tie(0);
  ll n,L;cin >> n >> L;
  vi a(n),b(n);
  rep(i,n)cin >> a[i] >> b[i];
  vi c(n);cin >> c;
  vi idx(n);
  iota(ALL(idx),0);
  sort(ALL(idx),[&](int i,int j){
    return a[i]-b[i] > a[j]-b[j];
  });
  vi ruiC(n+1);
  rep(i,n)ruiC[i+1] = ruiC[i] + c[i];
  vi rui(n+1);
  rep(i,n)rui[i+1] = rui[i] + a[idx[i]] - b[idx[i]];
  ll lst = n;
  rep(i,n)if(ruiC[i+1] >= rui[i+1]){
    lst = i;
    break;
  }
  min_priority_queue<P> que;
  int res = MOD;
  for(int i = n-1;i >= 0;i--){
    int A = a[idx[i]],B = b[idx[i]];
    while(!que.empty()){
      auto [x,y] = que.top();
      if(x <= A-B){
        chmin(lst,y);
        que.pop();
      }else break;
    }
    int k = LB(rui,L-A);
    int g = 0;
    if(k >= i+1){g = 1;
      k = LB(rui,L-A+(A-B));
    }
    if(k-1 < lst)chmin(res,k-g+1);
    que.push({rui[i+1]-ruiC[i],i});
  }
  cout << (res == MOD ? -1 : res) << "\n";
  

  return 0;
}
accuracy: 0.875
time_ms: 20
memory_kb: 9768
final_rank: 11

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

template <typename M, typename N, M (*f)(M, M), M (*g)(M, N), M (*m1)()>
struct SegmentTree {
    int sz, n;
    vector<M> data;
    SegmentTree(int _n = 0) : n(_n) {
        sz = 1;
        while (sz < _n)
            sz <<= 1;
        data.assign(2 * sz, m1());
    }
    void run(vector<M> &v) {
        for (int i = 0; i < (int)v.size(); i++)
            data[i + sz] = v[i];
        for (int k = sz - 1; k > 0; k--)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    void set(int k, const M &x) {
        k += sz;
        data[k] = x;
        while (k >>= 1)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    void update(int k, const N &x) {
        k += sz;
        data[k] = g(data[k], x);
        while (k >>= 1)
            data[k] = f(data[2 * k], data[2 * k + 1]);
    }
    M query(int a, int b) {
        M L = m1(), R = m1();
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1)
                L = f(L, data[a++]);
            if (b & 1)
                R = f(data[--b], R);
        }
        return f(L, R);
    }
    M operator[](const int &k) const {
        return data[k + sz];
    }
    vector<M> get() {
        return {data.begin() + sz, data.begin() + sz + n};
    }
    template <class F> int max_right(int L, F ch) const {
        int l = sz + L, w = 1;
        M ansL = m1();
        for (; L + w <= sz; l >>= 1, w <<= 1)
            if (l & 1) {
                if (not ch(f(ansL, data[l])))
                    break;
                ansL = f(ansL, data[l++]);
                L += w;
            }
        while (l <<= 1, w >>= 1) {
            if (L + w <= sz && ch(f(ansL, data[l]))) {
                ansL = f(ansL, data[l++]);
                L += w;
            }
        }
        return L;
    }
    template <class F> int min_left(int R, F ch) const {
        int r = sz + R, w = 1;
        M ansR = m1();
        for (; R - w >= 0; r >>= 1, w <<= 1)
            if (r & 1) {
                if (not ch(f(data[r - 1], ansR)))
                    break;
                ansR = f(data[--r], ansR);
                R -= w;
            }
        while (r <<= 1, w >>= 1) {
            if (R - w >= 0 && ch(f(data[r - 1], ansR))) {
                ansR = f(data[--r], ansR);
                R -= w;
            }
        }
        return R;
    }
};

/**
 * @brief Segment Tree
 */

ll f(ll A, ll B) {return min(A,B);}
ll g(ll A, ll B) {return B;}
ll e() {return INF;}

int main() {
    int N;
    ll L;
    cin >> N >> L;
    vector<pair<ll,ll>> A(N);
    vector<ll> C(N);
    rep(i,0,N) cin >> A[i].first >> A[i].second;
    rep(i,0,N) cin >> C[i];
    sort(ALL(A),[&](pair<ll,ll> p, pair<ll,ll> q){return p.first-p.second > q.first-q.second;});
    vector<ll> D(N);
    rep(i,0,N) D[i] = A[i].first-A[i].second;
    vector<ll> DS(N+1);
    DS[0] = 0;
    rep(i,0,N) DS[i+1] = DS[i] + max(D[i], 0LL);
    vector<ll> E0(N), E1(N-1);
    rep(i,0,N) E0[i] = A[i].first-A[i].second-C[i];
    rep(i,0,N-1) E1[i] = A[i+1].first-A[i+1].second-C[i];
    vector<ll> ES0(N+1), ES1(N);
    ES0[0] = ES1[0] = 0;
    rep(i,0,N) ES0[i+1] = ES0[i] + E0[i];
    rep(i,0,N-1) ES1[i+1] = ES1[i] + E1[i];
    SegmentTree<ll,ll,f,g,e> Seg0(N+1), Seg1(N);
    Seg0.run(ES0);
    Seg1.run(ES1);
    int ANS = inf;
    rep(i,0,N) {
        if (DS[i] + A[i].first >= L) {
            int ID = LB(DS, L - A[i].first);
            if (Seg0.query(1,ID+1) > 0) chmin(ANS, ID+1);
        }
        else if (DS[N] - max(D[i], 0LL) + A[i].first >= L) {
            int ID = LB(DS, L - A[i].first + max(D[i], 0LL));
            if (Seg0.query(1,i+1) > 0 && ES0[i] + Seg1.query(i+1, ID) - ES1[i] > 0) chmin(ANS, ID);
        }
    }
    cout << (ANS == inf ? -1 : ANS) << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 14128
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (lower_bound(ALL(A),x)-A.begin())
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
struct segtree{
    vi tree;
    int n;
    ll op(ll a,ll b){return max(a,b);}
    ll e(){return -1e18;}
    segtree(int _N){
        n=1;
        while(n<_N)n<<=1;
        tree.assign(2*n,e());
    }
    void set(int i,ll x){
        i+=n;
        tree[i]=x;
        while(i>1){
            i>>=1;
            tree[i]=op(tree[2*i],tree[2*i+1]);
        }
    }
    ll prod(int l,int r){
        l+=n;r+=n;
        ll L=e(),R=e();
        while(l<r){
            if(l%2)L=op(L,tree[l++]);
            if(r%2)R=op(tree[--r],R);
            l>>=1;r>>=1;
        }
        return op(L,R);
    }
};
struct minsegtree{
    vi tree;
    int n;
    ll op(ll a,ll b){return min(a,b);}
    ll e(){return 1e18;}
    minsegtree(int _N){
        n=1;
        while(n<_N)n<<=1;
        tree.assign(2*n,e());
    }
    void set(int i,ll x){
        i+=n;
        tree[i]=x;
        while(i>1){
            i>>=1;
            tree[i]=op(tree[2*i],tree[2*i+1]);
        }
    }
    ll prod(int l,int r){
        l+=n;r+=n;
        ll L=e(),R=e();
        while(l<r){
            if(l%2)L=op(L,tree[l++]);
            if(r%2)R=op(tree[--r],R);
            l>>=1;r>>=1;
        }
        return op(L,R);
    }
};
int main(){
    ll N,L;cin>>N>>L;
    vector<pi>A(N);
    REP(i,N)cin>>A[i].first>>A[i].second;
    REP(i,N)A[i].second=min(A[i].first,A[i].second);
    REP(i,N)A[i]=pi(A[i].first-A[i].second,-A[i].first);
    sort(ALL(A));
    reverse(ALL(A));
    REP(i,N)A[i].second*=-1;
    vi D(N+1);
    REP(i,N)D[i+1]=D[i]+A[i].first;
    vi C(N+1);
    REP(i,N)cin>>C[i+1];
    FOR(i,1,N+1)C[i]+=C[i-1];
    ll ans=1e18,m=*max_element(ALL(D));
    minsegtree seg(N+1),seg0(N);
    REP(i,N+1)seg.set(i,D[i]-C[i]);
    REP(i,N)seg0.set(i,D[i+1]-C[i]);
    REP(i,N){
        if(D[i]+A[i].second>=L){
            ll t=lower_bound(D.begin(),D.begin()+i,L-A[i].second)-D.begin();
            if(seg.prod(1,t+1)>0)ans=min(ans,t+1);
        }
        else if(m-A[i].first+A[i].second>=L){
            ll t=lower_bound(D.begin(),D.end(),L-A[i].second+A[i].first)-D.begin();
            if(t<i+1)continue;
            if(seg.prod(1,i+1)<=0)continue;
            if(seg0.prod(i+1,t)<=A[i].first)continue;
            ans=min(ans,t);
        }
    }
    if(ans>1e17)ans=-1;
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 10232
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
struct segtree{
    vi tree;
    int n;
    ll op(ll a,ll b){return max(a,b);}
    ll e(){return -1e18;}
    segtree(int _N){
        n=1;
        while(n<_N)n<<=1;
        tree.assign(2*n,e());
    }
    void set(int i,ll x){
        i+=n;
        tree[i]=x;
        while(i>1){
            i>>=1;
            tree[i]=op(tree[2*i],tree[2*i+1]);
        }
    }
    ll prod(int l,int r){
        l+=n;r+=n;
        ll L=e(),R=e();
        while(l<r){
            if(l%2)L=op(L,tree[l++]);
            if(r%2)R=op(tree[--r],R);
            l>>=1;r>>=1;
        }
        return op(L,R);
    }
};
int main(){
    ll N,L;cin>>N>>L;
    vector<pi>A(N);
    REP(i,N)cin>>A[i].first>>A[i].second;
    REP(i,N)A[i]=pi(A[i].first-A[i].second,-A[i].first);
    sort(ALL(A));
    reverse(ALL(A));
    segtree seg(N);
    REP(i,N)seg.set(i,-A[i].second);
    vi C(N);
    REP(i,N)cin>>C[i];
    FOR(i,1,N)C[i]+=C[i-1];
    int l=0;
    REP(i,N){
        if(seg.prod(0,N)+l>=L){
            cout<<i+1<<endl;
            return 0;
        }
        seg.set(i,-1e18);
        l+=A[i].first;
        if(l<=C[i]){
            cout<<-1<<endl;return 0;
        }
    }
    cout<<-1<<endl;
    return 0;
}
accuracy: 0.2916666666666667
time_ms: 50
memory_kb: 7192
final_rank: 19

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

const long long INF = (3LL << 59);

class drink {
public:
	long long a, b;
	drink() : a(0), b(0) {}
	drink(long long a_, long long b_) : a(a_), b(b_) {}
};

class segtree {
private:
	int sz;
	vector<long long> val;
public:
	segtree() : sz(0), val(vector<long long>()) {}
	segtree(int n) {
		sz = (n >= 3 ? 1 << (32 - __builtin_clz(n - 1)) : n);
		val.resize(sz * 2, -INF);
	}
	void update(int pos, long long x) {
		pos += sz;
		val[pos] = x;
		while (pos > 1) {
			pos /= 2;
			val[pos] = max(val[pos * 2], val[pos * 2 + 1]);
		}
	}
	long long rangemax(int l, int r) const {
		long long res = -INF;
		l += sz;
		r += sz;
		while (l != r) {
			if (l & 1) res = max(res, val[l++]);
			if (r & 1) res = max(res, val[--r]);
			l >>= 1;
			r >>= 1;
		}
		return res;
	}
};

int main() {
	// step #1. input
	int N; long long L;
	cin >> N >> L;
	vector<drink> D(N);
	for (int i = 0; i < N; i++) {
		cin >> D[i].a >> D[i].b;
	}
	vector<int> C(N);
	for (int i = 0; i < N; i++) {
		cin >> C[i];
	}

	// step #2. solve
	sort(D.begin(), D.end(), [&](const drink& d1, const drink& d2) {
		return d1.a - d1.b > d2.a - d2.b;
	});
	vector<long long> F(N);
	segtree seg1(N), seg2(N);
	for (int i = 0; i < N; i++) {
		F[i] = D[i].a - D[i].b;
		seg1.update(i, D[i].a);
		seg2.update(i, D[i].b);
	}
	int answer = -1;
	long long height = F[0];
	long long diff = F[0] + 1;
	long long diffmin = diff;
	for (int r = 1; r <= N; r++) {
		if (diffmin <= 0) {
			break;
		}
		int pos = lower_bound(F.begin(), F.end(), diffmin - 1, [](long long v1, long long v2) { return v1 > v2; }) - F.begin();
		if (pos < r - 1) {
			long long bmax = seg2.rangemax(pos, r - 1);
			long long h = height + bmax;
			if (h >= L) {
				answer = r;
				break;
			}
		}
		if (pos < r) {
			long long amax = seg1.rangemax(r - 1, N);
			long long h = height - F[r - 1] + amax;
			if (h >= L) {
				answer = r;
				break;
			}
		}
		if (r != N) {
			height += F[r];
			diff += F[r] - C[r - 1];
			if (r == 1) {
				diff -= 1;
			}
			diffmin = min(diffmin, diff);
		}
	}

	// step #3. output
	cout << answer << endl;

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 9920
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()
#define REPname(a,b,c,d,...) d
#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i,l,r) for(int i = l; i < r; i++)
#define REP1(i, x) REP2(i,0,x)
#define REP0(x) REP1(SPJ, x)
#define sz(x) int(x.size())

template <class T>
using V=vector<T>;

template <class T>
using VV=vector<V<T>>;

template<class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long ;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = V<vll>;
constexpr ll INF = 1e18;
constexpr int inf = 1e9;
template<class T>
inline bool chmax(T &a, T b){
	return a < b ? a=b, 1 : 0;
}
template <class T>
inline bool chmin(T &a, T b) {
	return a > b ? a = b, 1 : 0;
}

template <class T>
void view(T x) {
	cerr << x;
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ", ";}
	cerr << "}";
	cerr << endl;
}


template <class T>
void view(VV<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ",\n";}
	cerr << "}";
	cerr << endl;
}


// template <c0lass T>
void view(int x) {
	cerr << x;
}

#ifdef LOCAL
void debug_out() {}
template <class T>
void debug_out(T x) {
	view(x);
}
template <class H, class... T>
void debug_out(H h, T... t) {
	view(h);
	cerr << ", ";
	debug_out(t...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
using vvi = V<vi>;

struct uf{
	vector<int> dat;
	uf(int n) : dat(n, -1) {}
	int root(int x) 
	{
		int& p = dat[x];
		if(p < 0) return x;
		return p = root(p);
	}
	bool merge(int x, int y) {
		x = root(x);
		y = root(y);
		if(x == y) return false;
		if(-dat[x] < -dat[y]) swap(x, y);
		dat[x] += dat[y];
		dat[y]  = x;
		return true;
	}
};

ll modpow(ll x, ll n, ll md){
	ll ret = 1 % md;
	while(n > 0){
		if(n & 1) {ret *= x; ret %= md;}
		n >>= 1;
		x *= x;
		x %= md;
	}
	if(ret < 0) ret += abs(md);
	return ret;
}

using S = ll;
using F = ll; // +
constexpr ll e = INF;
constexpr ll id = 0LL;
constexpr ll replace_e = e;
ll op(ll a, ll b) {return min(a,b);}
ll mapping(F f, S s) {return S(f+s);}
ll composition(F f, F g) {return f+g;}
struct node {
	node *l = nullptr;
	node *r = nullptr;
	int lo, hi;
	ll mset = e;
	ll madd = id;
	ll val = e;
	node(int lo, int hi) : lo(lo), hi(hi) {}
	node (vll& v, int lo, int hi) : lo(lo), hi(hi) {
		if(lo + 1 < hi) {
			int mid  = lo + (hi - lo) / 2;
			l  = new node (v, lo, mid);
			r = new node(v, mid, hi);
			val = op(l->val, r->val);
		}
		else {
			val  = v[lo];
		}
	}

	S query(int L, int R) {
		if(R <= lo || hi <= L) return e;
		if(L <=lo && hi  <= R) return val;
		push();
		return op(l->query(L, R), r->query(L,R));
	}

	void set(int L, int R, ll x) {
		if(R <= lo || hi <= L) return;
		if(L <= lo && hi <= R) mset = val = x, madd = id;
		else {
			push(), l->set (L, R, x) , r->set(L,R,x);
			val = op(l->val, r->val);
		}
	}

	void add(int L, int R, ll x) {
		if(R <= lo || hi <= L) return;
		if(L <= lo && hi <= R) {
			if(mset != replace_e) mset = mapping(x, mset);
			else madd = composition(x, madd);
			val = mapping(x, val);
		} else {
			push(), l->add(L, R, x), r->add(L, R, x);
			val = op(l->val, r->val);
		}
	}

	void push() {
		if(!l) {
			int mid = lo + (hi - lo) / 2;
			l = new node(lo, mid);
			r = new node(mid, hi);
		}
		if(mset != replace_e)
			l->set(lo, hi, mset), r->set(lo, hi, mset), mset = replace_e;
		else if(madd)
			l->add(lo, hi, madd), r->add(lo, hi, madd), madd = id;
	}
};

int solve(int n){
	ll len; cin >> len;
	V<pair<ll, ll>> up_bonus;
	ll largest_bonus = -INF;
	rep(n) {
		ll a, b; cin >> a >> b;
		ll up = a - b;
		if(up > 0) {
			up_bonus.emplace_back(up, b);
		} else if(a > 0) {
			chmax(largest_bonus, a);
		}
	}
	vll criminals = {0LL};
	rep(n) {
		ll c;
		cin >> c; 
		criminals.push_back(criminals.back() + c);
	}

	sort(all(up_bonus));
	reverse(all(up_bonus));

	vector<ll> s = {0};
	for(auto [c, d] : up_bonus) {
		s.push_back(s.back() + c);
	}

	const int plus_size = up_bonus.size();
	if(plus_size == 0) {
		if(len <= largest_bonus) return 1;
		return -1;
	}

	vector<ll> tab = s;
	tab.front() = INF;
	tab.at(1) = INF;

	rep(i, 2, int(tab.size())) {
		tab[i] -= criminals[i-1];
	}

	node* rmq = new node(tab, 0, int(tab.size()));

	int ans = n + 10;

	rep(i, plus_size) {
		auto [up, bonus] = up_bonus.at(i);

		if(i && s[i] <= criminals[i]) break;
		if(s[i] + largest_bonus >= len) chmin(ans, i + 1);

		const int from_here = int(lower_bound(all(s), len - bonus) - s.begin());
		if(from_here == int(s.size())) continue;
		if(from_here <= i + 1) {chmin(ans, i + 1); continue;}

		if(rmq->query(i + 2, from_here + 1) <= up) continue;

		chmin(ans, from_here);
	}

	if(s.back() > criminals.back() && s.back() + largest_bonus >= len) chmin(ans, plus_size + 1);

	if(ans > n) return -1;
	return ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	srand((unsigned)time(NULL));
	int n;
	while(cin >> n && n) cout<< solve(n) << '\n';
}
accuracy: 1
time_ms: 40
memory_kb: 19376
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()
#define REPname(a,b,c,d,...) d
#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i,l,r) for(int i = l; i < r; i++)
#define REP1(i, x) REP2(i,0,x)
#define REP0(x) REP1(SPJ, x)
#define sz(x) int(x.size())

template <class T>
using V=vector<T>;

template <class T>
using VV=vector<V<T>>;

template<class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long ;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = V<vll>;
constexpr ll INF = 1e18;
constexpr int inf = 1e9;
template<class T>
inline bool chmax(T &a, T b){
	return a < b ? a=b, 1 : 0;
}
template <class T>
inline bool chmin(T &a, T b) {
	return a > b ? a = b, 1 : 0;
}

template <class T>
void view(T x) {
	cerr << x;
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ", ";}
	cerr << "}";
	cerr << endl;
}


template <class T>
void view(VV<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ",\n";}
	cerr << "}";
	cerr << endl;
}


// template <c0lass T>
void view(int x) {
	cerr << x;
}

#ifdef LOCAL
void debug_out() {}
template <class T>
void debug_out(T x) {
	view(x);
}
template <class H, class... T>
void debug_out(H h, T... t) {
	view(h);
	cerr << ", ";
	debug_out(t...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
using vvi = V<vi>;

struct uf{
	vector<int> dat;
	uf(int n) : dat(n, -1) {}
	int root(int x) 
	{
		int& p = dat[x];
		if(p < 0) return x;
		return p = root(p);
	}
	bool merge(int x, int y) {
		x = root(x);
		y = root(y);
		if(x == y) return false;
		if(-dat[x] < -dat[y]) swap(x, y);
		dat[x] += dat[y];
		dat[y]  = x;
		return true;
	}
};

ll modpow(ll x, ll n, ll md){
	ll ret = 1 % md;
	while(n > 0){
		if(n & 1) {ret *= x; ret %= md;}
		n >>= 1;
		x *= x;
		x %= md;
	}
	if(ret < 0) ret += abs(md);
	return ret;
}

using S = ll;
using F = ll; // +
constexpr ll e = INF;
constexpr ll id = 0LL;
constexpr ll replace_e = e;
ll op(ll a, ll b) {return min(a,b);}
ll mapping(F f, S s) {return S(f+s);}
ll composition(F f, F g) {return f+g;}
struct node {
	node *l = nullptr;
	node *r = nullptr;
	int lo, hi;
	ll mset = e;
	ll madd = id;
	ll val = e;
	node(int lo, int hi) : lo(lo), hi(hi) {}
	node (vll& v, int lo, int hi) : lo(lo), hi(hi) {
		if(lo + 1 < hi) {
			int mid  = lo + (hi - lo) / 2;
			l  = new node (v, lo, mid);
			r = new node(v, mid, hi);
			val = op(l->val, r->val);
		}
		else {
			val  = v[lo];
		}
	}

	S query(int L, int R) {
		if(R <= lo || hi <= L) return e;
		if(L <=lo && hi  <= R) return val;
		push();
		return op(l->query(L, R), r->query(L,R));
	}

	void set(int L, int R, ll x) {
		if(R <= lo || hi <= L) return;
		if(L <= lo && hi <= R) mset = val = x, madd = id;
		else {
			push(), l->set (L, R, x) , r->set(L,R,x);
			val = op(l->val, r->val);
		}
	}

	void add(int L, int R, ll x) {
		if(R <= lo || hi <= L) return;
		if(L <= lo && hi <= R) {
			if(mset != replace_e) mset = mapping(x, mset);
			else madd = composition(x, madd);
			val = mapping(x, val);
		} else {
			push(), l->add(L, R, x), r->add(L, R, x);
			val = op(l->val, r->val);
		}
	}

	void push() {
		if(!l) {
			int mid = lo + (hi - lo) / 2;
			l = new node(lo, mid);
			r = new node(mid, hi);
		}
		if(mset != replace_e)
			l->set(lo, hi, mset), r->set(lo, hi, mset), mset = replace_e;
		else if(madd)
			l->add(lo, hi, madd), r->add(lo, hi, madd), madd = id;
	}
};

int solve(int n){
	ll len; cin >> len;
	V<pair<ll, ll>> up_bonus;
	ll largest_bonus = -1;
	rep(n) {
		ll a, b; cin >> a >> b;
		ll up = a - b;
		if(up > 0) {
			up_bonus.emplace_back(up, b);
		} else if(a > 0) {
			chmax(largest_bonus, a);
		}
	}
	vll criminals = {0LL};
	rep(n) {
		ll c;
		cin >> c; 
		criminals.push_back(criminals.back() + c);
	}

	sort(all(up_bonus));
	reverse(all(up_bonus));

	vector<ll> s = {0};
	for(auto [c, d] : up_bonus) {
		s.push_back(s.back() + c);
	}

	const int ss = int(s.size());

	vector<ll> tab = s;
	if(ss < 2) {
		if(len <= largest_bonus) return 1;
		return -1;
	}

	tab.front() = INF;
	tab.at(1) = INF;

	rep(i, 2, ss) {
		tab[i] -= criminals[i-1];
	}

	node* rmq = new node(tab, 0, ss);

	int ans = n + 10;

	rep(i, int(up_bonus.size())) {
		auto [up, bonus] = up_bonus.at(i);

		if(i && s[i] <= criminals[i]) break;
		if(s[i] + largest_bonus >= len) chmin(ans, i + 1);

		const int from_here = int(lower_bound(all(s), len - bonus) - s.begin());
		if(from_here == ss) continue;
		if(from_here <= i + 1) {chmin(ans, i + 1); continue;}

		if(rmq->query(i + 2, from_here + 1) <= up) continue;

		chmin(ans, from_here);
	}

	if(ans > n) return -1;
	return ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	srand((unsigned)time(NULL));
	int n;
	while(cin >> n && n) cout<< solve(n) << '\n';
}
accuracy: 0.9791666666666666
time_ms: 40
memory_kb: 19444
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myrand(ll B){
    return (ull)rng() % B;
}

const int mx = 1e9;
const ll inf = 1e18;

struct segtree {
    using S = ll; // 例
    S op(S a,S b) {return min(a,b);}
    S e() {return inf;}

    int n;
    vector<S> tree;
    segtree(int n) : n(n), tree(vector<S>(n*2, e())) {}

    void update(int pos,S val){
        pos += n; tree[pos] = val;
        while(pos > 1){
            tree[pos/2] = op(tree[pos], tree[pos^1]);
            pos /= 2;
        }
    }
    // [l,r)
    S query(int l, int r) {
        S sml = e(), smr = e();
        for(l += n, r += n; l < r; l >>= 1, r >>= 1){
            if(l%2) sml = op(sml, tree[l++]);
            if(r%2) smr = op(tree[--r], smr);
        }
        return op(sml,smr);
    }
};


int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    ll L; cin >> L;
    vector<pair<ll,ll>> v(n);
    for (int i = 0; i < n; ++i) {
        ll a,b; cin >> a >> b;
        v[i] = {a-b, a};
    }
    sort(v.rbegin(), v.rend());

    vector<ll> c(n);
    for (int i = 0; i < n; ++i) {
        cin >> c[i];
    }
    int res = mx;
    // ソート順で使う場合
    {
        vector<ll> rmx(n);
        for (int i = n-1; i >= 0; --i) {
            rmx[i] = max(rmx[i], v[i].second);
            if(i+1 < n){
                rmx[i] = max(rmx[i], rmx[i+1]);
            }
        }
        ll ss = 0;
        ll cs = 0;
        if(rmx[0] >= L) res = 1;
        for (int i = 0; i < n - 1; ++i) {
            ss += v[i].first;
            cs += c[i];
            if(ss <= cs) break;
            if(ss + rmx[i+1] >= L){
                res = min(res, i+2);
            }
        }
    }
    // aでかいのを後回しにする場合
    {
        vector<ll> dif(n-1);
        for (int i = 0; i < n - 1; ++i) {
            dif[i] = v[i+1].first-c[i];
        }
        segtree seg(n-1);
        vector<ll> dsum(n);
        for (int i = 0; i < n - 1; ++i) {
            dsum[i+1] = dsum[i] + dif[i];
            seg.update(i, dsum[i+1]);
        }

        vector<ll> sum(n+1);
        for (int i = 0; i < n; ++i) {
            sum[i+1] = sum[i] + v[i].first;
        }
        ll ss = 0;
        ll cs = 0;
        for (int i = 0; i+1 < n; ++i) {
            // iを後回し
            int l = i-1, r = n;
            while(r-l > 1){
                int mid = (l+r)/2;
                ll u = sum[mid+1]-v[i].first+v[i].second;
                if(u >= L){
                    r = mid;
                }
                else{
                    l = mid;
                }
            }
            bool ok = true;
            if(r == n or r == i) ok = false;
            // 正当性確認
            if(ok){
                // [i,r)のdifの前から累積和の最小値を調べる
                ll pds = dsum[i];
                ll mi = seg.query(i,r);
                if(mi-pds+ss-cs > 0){
                    res = min(res, r+1);
                }
            }
            // 次の更新
            {
                ss += v[i].first;
                cs += c[i];
                if(ss <= cs) break;
            }
        }
    }
    if(res == mx) res = -1;
    cout << res << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 9284
final_rank: 3