链接
题目描述
样例输入
3 3 3 8
3 2 3
2 3 1
样例输出
10
思路
假设选择的矩阵左上角为(ax1,by1),右下角为(ax2,by2)
那么这个矩阵的权值和就是
a
x
1
∗
(
b
y
1
+
b
y
2
+
b
y
3...
)
ax1 * (by1+by2+by3...)
ax1∗(by1+by2+by3...)
.
.
.
就可以推到
(
a
x
1
+
a
x
2
+
a
x
3
+
.
.
.
a
x
n
)
∗
(
b
y
1
+
b
y
2
+
b
y
3
+
.
.
.
b
y
m
)
(ax1+ax2+ax3+...axn)*(by1+by2+by3+...bym)
(ax1+ax2+ax3+...axn)∗(by1+by2+by3+...bym)
那么可以预处理出b的任意区间和
然后枚举a 的区间然后再二分求出b的区间的个数就好了
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
ll n, m, l, r, ans, t;
ll a[1005], b[1005], c[1001005], sum[1005], sumb[1005];
int main()
{
scanf("%lld%lld%lld%lld", &n, &m, &l, &r);
for(int i = 1; i <= n; ++i)
scanf("%lld", &a[i]), sum[i] = sum[i - 1] + a[i];
for(int i = 1; i <= m; ++i)
scanf("%lld", &b[i]), sumb[i] = sumb[i - 1] + b[i];
for(int i = 1; i <= m; ++i)
for(int j = i; j <= m; ++j)
c[++t] = sumb[j] - sumb[i - 1];
sort(c + 1, c + t + 1);
for(int i = 1; i <= n; ++i)
for(int j = i; j <= n; ++j)
{
ll L, R;
ll suma = sum[j] - sum[i - 1];
if(suma != 0) L = ceil(l * 1.0 / suma * 1.0), R = r * 1.0 / suma * 1.0;
else L = l, R = r;
int le = lower_bound(c + 1, c + t + 1, L) - c;
int ri = upper_bound(c + 1, c + t + 1, R) - c;
ans += ri - le;
}
printf("%lld", ans);
return 0;
}