1. 程式人生 > >【CodeForces - 1060C】【Maximum Subrectangle 】

【CodeForces - 1060C】【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):

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

解題報告:給我們兩個矩陣(行,列),二者做矩陣乘法,然後得到新的矩陣C,其中我們找到其子矩陣,和小於等於X 且範圍儘可能的大。這裡用到了一個矩陣求和的小裝換,子陣的和等於乘出來他的行列和的乘積(很溜的規律)。這樣咱們就可以將而為矩陣的求和變為最初兩個一維矩陣的求和求積。然後矩陣的話,是要求範圍儘可能的大,所以在固定一邊的長度情況下,這邊的值越小,對方的值就要越大,那麼長度就會越大。然後面積就變大。

ac程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn = 2050;
ll a[maxn],b[maxn];
ll suma[maxn],sumb[maxn];

int main()
{
	ll x,n,m;
	while(scanf("%lld%lld",&n,&m)!=EOF)
	{
		a[0]=b[0]=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%lld",&a[i]);
			a[i]=a[i]+a[i-1];	
		}	
		for(int i=1;i<=m;i++)
		{
			scanf("%lld",&b[i]);
			b[i]=b[i]+b[i-1];
		}
		scanf("%lld",&x);
		memset(suma,inf,sizeof(suma));
		memset(sumb,inf,sizeof(sumb));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				if(i+j-1>n) break;
				suma[i]=min(suma[i],a[i+j-1]-a[j-1]);
			}
		for(int i=1;i<=m;i++)
			for(int j=1;j<=m;j++)
			{
				if(i+j-1>m) break;
				sumb[i]=min(sumb[i],b[i+j-1]-b[j-1]);
			}
		ll ans=0;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
				if((ll)suma[i]*sumb[j]<=x)
					ans=max(ans,(ll)i*j*1);
			}
		printf("%lld\n",ans);
	}	
	return 0;
}