1G - Maximum Subrectangle

You are given two arrays aa and bb of positive integers, with length nn and mmrespectively.

Let cc be an n×mn×m matrix, where ci,j=ai⋅bjci,j=ai⋅bj.

You need to find a subrectangle of the matrix cc such that the sum of its elements is at most xx, and its area (the total number of elements) is the largest possible.

Formally, you need to find the largest number ss such that it is possible to choose integers x1,x2,y1,y2x1,x2,y1,y2 subject to 1≤x1≤x2≤n1≤x1≤x2≤n, 1≤y1≤y2≤m1≤y1≤y2≤m, (x2−x1+1)×(y2−y1+1)=s(x2−x1+1)×(y2−y1+1)=s, and

∑i=x1x2∑j=y1y2ci,j≤x.∑i=x1x2∑j=y1y2ci,j≤x.

 

Input

The first line contains two integers nn and mm (1≤n,m≤20001≤n,m≤2000).

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤20001≤ai≤2000).

The third line contains mm integers b1,b2,…,bmb1,b2,…,bm (1≤bi≤20001≤bi≤2000).

The fourth line contains a single integer xx (1≤x≤2⋅1091≤x≤2⋅109).

Output

If it is possible to choose four integers x1,x2,y1,y2x1,x2,y1,y2 such that 1≤x1≤x2≤n1≤x1≤x2≤n, 1≤y1≤y2≤m1≤y1≤y2≤m, and ∑x2i=x1∑y2j=y1ci,j≤x∑i=x1x2∑j=y1y2ci,j≤x, output the largest value of (x2−x1+1)×(y2−y1+1)(x2−x1+1)×(y2−y1+1) among all such quadruplets, otherwise output 00.

Examples

Input

3 3
1 2 3
1 2 3
9

Output

4

Input

5 1
5 4 2 4 5
2
5

Output

1

Note

Matrix from the first sample and the chosen subrectangle (of blue color):

1 23
246
369

Matrix from the second sample and the chosen subrectangle (of blue color):

1084810

题意:

a[n]数组和b[m]数组,元素相乘形成矩阵c(n*m);给出一个数X;求一个小矩阵,其中的元素满足之和小于X,问这个小矩阵(小长方形)的面积,也就是小矩阵中元素的最大个数。

思路:

若数组a为: 2  1  3;数组b为1  2  3;则maa为:2  3  6 ;mbb为:1  3  6。组成的数组c为

2 13
426
63

9

X为9。蓝色矩阵中元素之和满足(a1+a2)*(b1+b2)=maa[2]*mbb[2].

结合代码,应该就能明白了。


代码如下:

  1. #include<iostream>

  2. #include<cstdio>

  3. #include<cstring>

  4. #define LL long long

  5. using namespace std;

  6. int n, m;

  7. LL a[2005], b[2005], x;

  8. LL suma[2005], sumb[2005], ans, maa[2005], mab[2005];

  9. int main() {

  10. memset(maa, 0x3f3f3f3f, sizeof(maa));//将maa设置为最大数组

  11. memset(mab, 0x3f3f3f3f, sizeof(mab));//将mbb设置为最大数组

  12. //可以参考转载的memset算法
  13. scanf("%d%d", &n, &m);

  14.    
    for(int i = 1; i <= n; i ++)//输入a数组
    {
           
    scanf("%lld", &a[i]);
            suma[i] = suma[i -
    1] + a[i];//记录a数组连续相加的元素
           
    for(int j = 1; j <= i; j ++)
            maa[j] = min(maa[j], suma[i] - suma[i - j]);//从大到小排序
        }
       
       
    for(int i = 1; i <= m; i ++)
    {
           
    scanf("%lld", &b[i]);
            sumb[i] = sumb[i -
    1] + b[i];
           
          
    for(int j = 1; j <= i; j ++)
            mab[j] = min(mab[j], sumb[i] - sumb[i - j]);

  15. //printf("maa[%d]= %lld\n",j,maa[j]);
        }
       
        scanf
    ("%lld", &x);
        LL j =
    0;
       
       
    for(LL i = m; i >= 1; i --)
        {
           
    while(j < n && maa[j + 1] * mab[i] <= x)//一一尝试
            j ++;
           ans = max(ans, j * i);
        }
       
       
    printf("%lld\n", ans);
       
    return 0;
    }

  16.    

如有疑问,请私信。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值