2021-08-09 SSL 模拟赛 T2

2021-08-09 SSL 模拟赛 T2

这道阴间的题目竟然也没有标题。
在这里插入图片描述

思路:

对于一个矩阵,我们设它的左上角为 [ x 1 , y 1 ] [x_1,y_1] [x1,y1],右下角为 [ X 2 , Y 2 ] [X_2,Y_2] [X2,Y2],那么这个矩阵的和为
a [ x 1 ] ∗ ( b [ y 1 ] + b [ y 1 + 1 ] + ⋅ ⋅ ⋅ + b [ y 2 ] ) + ⋅ ⋅ ⋅ + a [ x 2 ] ∗ ( b [ y 1 ] + b [ y 1 + 1 ] + ⋅ ⋅ ⋅ + b [ y 2 ] ) a[x_1]*(b[y_1]+b[y_1+1]+···+b[y_2])+···+a[x_2]*(b[y_1]+b[y_1+1]+···+b[y_2]) a[x1](b[y1]+b[y1+1]++b[y2])++a[x2](b[y1]+b[y1+1]++b[y2])
= ∑ i = x 1 x 2 a [ i ] ∗ ∑ j = y 1 y 2 b [ j ] =\sum_{i=x_1}^{x_2}a[i]*\sum_{j=y_1}^{y_2}b[j] =i=x1x2a[i]j=y1y2b[j]
我们发现, x 1 , x 2 x_1,x_2 x1,x2 y 1 , y 2 y_1,y_2 y1,y2之间没有什么直接的联系。
那么我们可以预处理出 y 的所有区间和,再去枚举 x 1 , x 2 x_1,x_2 x1,x2
然后我们利用前缀和可以很轻松的求出 a [ x 1 ] — — a [ x 2 ] a[x_1]——a[x_2] a[x1]a[x2]的区间和
然后我们用询问区间除去这个区间和,那么剩下的就是 y 坐标的取值范围了
因为我们已经预处理出了关于 y 的每个区间和,将其排序后进行二分查找在查询区间内的个数,累加即可。

伟大的 e l b a     t e a c h e r elba~~~teacher elba   teacher 给出的思路 (本人解法的来源):
在这里插入图片描述

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
ll n,m,a[1200],b[1200]; 
ll L,R,mid,sa[1200],sb[1200];
ll c[1001*1001],top,le,ri,ans;
ll ask(ll le,ll ri)
{
	//这两个是二分查找函数,非常方便不会用的可以自行上网搜索
	ll x=lower_bound(c+1,c+top+1,le)-c; //返回第一个>= x 的值
	ll y=upper_bound(c+1,c+top+1,ri)-c; //返回第一个 > y 的值
	return y-x; //合法个数
}
void work()
{
	rep(i,1,n) //枚举x1,x2
	 rep(j,i,n)
	 {
	 	ll v=sa[j]-sa[i-1];
	 	ll le=L/v,ri=R/v;
	 	if(L%v) ++le; //注意除法时多出来的余数,左边界向上取整,右边界向下取整
	 	ans+=ask(le,ri);
	 }
	printf("%lld",ans);
}
int main()
{
	scanf("%lld%lld%lld%lld",&n,&m,&L,&R);
	rep(i,1,n)
	{
		scanf("%lld",&a[i]);
		sa[i]=sa[i-1]+a[i];
	}
	rep(i,1,m)
	{
		scanf("%lld",&b[i]);
		sb[i]=sb[i-1]+b[i];
	}
	rep(i,1,m)
	 rep(j,i,m)
	  c[++top]=sb[j]-sb[i-1]; //预处理出关于 y 的所有区间和
	sort(c+1,c+top+1);
	work();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值