CodeForces - 609D Gadgets for dollars and pounds【二分+贪心】

版权声明:转载什么的好说,附上友链就ojek了,同为咸鱼,一起学习。 https://blog.csdn.net/sodacoco/article/details/86570349

参看资料:

https://www.cnblogs.com/qldabiaoge/p/8519501.html


题目:

Nura wants to buy k gadgets. She has only s burles for that. She can buy each gadget for dollars or for pounds. So each gadget is selling only for some type of currency. The type of currency and the cost in that currency are not changing.

Nura can buy gadgets for n days. For each day you know the exchange rates of dollar and pound, so you know the cost of conversion burles to dollars or to pounds.

Each day (from 1 to n) Nura can buy some gadgets by current exchange rate. Each day she can buy any gadgets she wants, but each gadget can be bought no more than once during n days.

Help Nura to find the minimum day index when she will have k gadgets. Nura always pays with burles, which are converted according to the exchange rate of the purchase day. Nura can't buy dollars or pounds, she always stores only burles. Gadgets are numbered with integers from 1 to m in order of their appearing in input.

Input

First line contains four integers n, m, k, s (1 ≤ n ≤ 2·105, 1 ≤ k ≤ m ≤ 2·105, 1 ≤ s ≤ 109) — number of days, total number and required number of gadgets, number of burles Nura has.

Second line contains n integers ai (1 ≤ ai ≤ 106) — the cost of one dollar in burles on i-th day.

Third line contains n integers bi (1 ≤ bi ≤ 106) — the cost of one pound in burles on i-th day.

Each of the next m lines contains two integers ti, ci (1 ≤ ti ≤ 2, 1 ≤ ci ≤ 106) — type of the gadget and it's cost. For the gadgets of the first type cost is specified in dollars. For the gadgets of the second type cost is specified in pounds.

Output

If Nura can't buy k gadgets print the only line with the number -1.

Otherwise the first line should contain integer d — the minimum day index, when Nura will have k gadgets. On each of the next k lines print two integers qi, di — the number of gadget and the day gadget should be bought. All values qi should be different, but the values di can coincide (so Nura can buy several gadgets at one day). The days are numbered from 1 to n.

In case there are multiple possible solutions, print any of them.

Examples

Input

5 4 2 2
1 2 3 2 1
3 2 1 2 3
1 1
2 1
1 2
2 2

Output

3
1 1
2 3

Input

4 3 2 200
69 70 71 72
104 105 106 107
1 1
2 2
1 2

Output

-1

Input

4 3 1 1000000000
900000 910000 940000 990000
990000 999000 999900 999990
1 87654
2 76543
1 65432

Output

-1

题目大意:

       给定 n 天的美元汇率(a1...an),英镑汇率(b1...bn); m种物品包括,物品类型(t1...tm) 物品花费(c1...cm);k 代表

需要买多少个物品,s 代表原来拥有的卢布总数。

       求解能买到k件物品的最小天数。

     【一天可以买多个物品,但是一个物品只能买一次】 

     【货币可以在任意一天兑换成任意数目的美元或者英镑】

解题思路:

      理解题意是关键,

      1》假设今天是第三天,那么我可以在第一天,第二天,第三天选择汇率最小的那一天用同样多的卢布换取最大的美元或者英镑数目;

       2》一天可以买多个物品,但是一个物品只能买一次

       3》目的是求最小天数,就是找在尽量靠前的天数里面 最小美元汇率 与 最小英镑汇率,能否满足买到 k 件物品。

       4》第 i 天如果能够买到 k 件物品,那么尝试再往前一天能否 买到,使天数尽量小;如果不能够买到,就向后寻找;如果所有的天数都不满足,那么输出 -1。

代码实现:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 200010
int a[maxn],b[maxn],c[maxn],t[maxn];
int am[maxn],bm[maxn],ida[maxn],idb[maxn],id[maxn];
int n,m,k,s;
struct node
{
    long long cost;
    int idx;
}qu[maxn];
int cmp(node a,node b)
{
    return a.cost<b.cost;
}
long long check(int x)
{
    long long ans=0;
    for (int i=1 ;i<=m ;i++ ){
        if (t[i]==1) qu[i].cost=(long long)c[i]*(long long)am[x];
        else qu[i].cost=(long long)c[i]*(long long)bm[x];
        qu[i].idx=i;//m种商品;
    }
    sort(qu+1,qu+1+m,cmp); //排序,选择最少的k个
    for (int i=1 ;i<=k ;i++)
        ans+=qu[i].cost; //累加和
    return ans;
}
int main() {
    while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF){
        am[0]=bm[0]=100000000;
        for (int i=1 ;i<=n ;i++){
            scanf("%d",&a[i]);
            if (a[i]<am[i-1]) {
                am[i]=a[i]; //当前兑换英镑最小汇率
                ida[i]=i;   //最小汇率的天数
            }else {
                am[i]=am[i-1];
                ida[i]=ida[i-1]; //这是连续的
            }
        }
        for (int i=1 ; i<=n ; i++) {
            scanf("%d",&b[i]);
            if (b[i]<bm[i-1]) {
                bm[i]=b[i];
                idb[i]=i;
            } else {
                bm[i]=bm[i-1];
                idb[i]=idb[i-1];    //兑换美元的最小值及天数
            }
        }
        //进行二分;
        for (int i=1 ;i<=m ;i++)
            scanf("%d%d",&t[i],&c[i]); //类型及需要的钱数
        long long r=n,l=0,mid,d=-1;
        while(l<=r) {        //二分找最小天数
            mid=(l+r)/2;
            if (check(mid)<=s) {
                r=mid-1;
                d=mid;//最少的天数
                for (int i=1 ;i<=k ;i++){
                    id[i]=qu[i].idx;
                }
            }else l=mid+1;
        }
        printf("%lld\n",d);
        if(d==-1) continue;
        int x=d;
        for (int i=1 ;i<=k ;i++){
            printf("%d %d\n",id[i],t[id[i]]==1?ida[x]:idb[x]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sodacoco/article/details/86570349