CF1060C题解
为了摆脱小凯的阴影,我开始刷CF上的思维题
模拟
由乘法分配律,有\(\sum_{i=x1}^{x2}\sum_{j=y1}^{y2}c_{i,j}=\sum_{i=x1}^{x2}\sum_{j=y1}^{y2}a_i*b_j=\sum_{i=x1}^{x2}a_i*\sum_{j=y1}^{y2}b_j\)
故问题转变为选取 a,b 的两个字段,使其乘积 ≤ x,且面积最大
刚开始的思路是可以\(n^2\)枚举a的所有区间,对于每个区间,若权值和为v,则在权值 <= x/v 的区间中选取长度最长的,可以用树状数组+离散化 or 动态开点权值线段树维护,复杂度\(O(N^2logN)\)
后来看了题解有一种更简单的思路,若区间长度一定,则权值越小越好,故记录长度为i的最小权值,复杂度可降至\(O(N^2)\)
#include<bits/stdc++.h>
using namespace std;
#define go(i,a,b) for(int i=a;i<=b;++i)
#define com(i,a,b) for(int i=a;i>=b;--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define fo(i,a) for(int i=0;i<a;++i)
#define il inline
#define int long long
const int inf=0x3f3f3f3f,N=2e3+10;
int n,m,a[N],b[N],lim,f[N],g[N];
il void read(int &x){
x=0;char c=getchar(),f=1;
while(!isdigit(c)){ if(c=='-') f=-1; c=getchar(); }
while(isdigit(c)){ x=x*10+c-'0'; c=getchar(); }
x*=f;
}
il void gmin(int &x,int y){
x=x<y?x:y;
}
signed main(){
//freopen("input.txt","r",stdin);
read(n),read(m);
go(i,1,n) read(a[i]),a[i]+=a[i-1];
go(i,1,m) read(b[i]),b[i]+=b[i-1];
read(lim);
mem(f,0x3f),mem(g,0x3f);
go(i,1,n)
go(j,i,n)
gmin(f[j-i+1],a[j]-a[i-1]);
go(i,1,m)
go(j,i,m)
gmin(g[j-i+1],b[j]-b[i-1]);
int ans=0;
go(i,1,n)
go(j,1,m)
if(f[i]*g[j]<=lim)
ans=max(ans,i*j);
cout<<ans;
return 0;
}