ccpc 2050 大厦

Problem Description

现在就让我们来大胆地畅想2050。我们乘坐着无人驾驶的飞行汽车,驰骋在城市的街头,感受着都市的繁华。

我们看到了一栋高楼大厦,大厦的墙面可以看做一个 W×H 的矩形,我们把它的左下角当成(0,0),右上角当成(W,H)。上面分布着一些LED灯,这些LED灯与地面呈45度倾斜,并且从矩形的边界延伸到另一边界,把大厦分成了若干个区域。我们想数一下这个图里面存在多少个与地面成45度角的矩形,其中四条边都是LED灯的一部分。

Input

第一行一个正整数 T (T≤10) 表示数据组数。
对于每组数据,第一行 W,H,n,m (1≤W,H≤109,0≤n,m≤103) 表示矩形的长和宽,以及两种方向的LED灯的个数。
接下来一行 n 个整数c (1≤c≤W+H−1),表示这个LED灯可以表示成 x+y=c 的形式,保证 c 两两不同。
接下来一行 m 个整数 c (1−H≤c≤W−1),表示这个LED灯可以表示成 x−y=c 的形式,保证 c 两两不同。

Output

对于每组数据,输出一个整数表示答案,由于答案可能很大,对 109+7 取模。

Sample Input

 

1 21 12 6 5 4 8 14 20 26 30 -6 -1 2 10 14

Sample Output

 

19

Source

 

Test Contest

思路:感觉榜单被带歪了,其实这道题不是很难。看图:

因此我们我们考虑对c1的序列进行排序,任意选取两个c2的值,在c1中二分查询一个满足上述不等式的区间[l,r],(因此要满足r>l)那么在上述区间内任意选择两个c1都和这两个c2都能构成满足题意的解,因此对答案的贡献是:(r-l)*(r-l+1)/2。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

ll W,H,n,m;
ll a[1005];
ll b[1005];

const int MOD=1e9+7;

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld %lld %lld %lld",&W,&H,&n,&m);
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		for(int j=1;j<=m;j++)
			scanf("%lld",&b[j]);
		sort(a+1,a+1+n);
		sort(b+1,b+1+m);
		ll l,r;
		ll low1,high1,low2,high2;
		ll re=0;
		for(int i=1;i<m;i++)
		{
			low1=max(b[i],-b[i]);
			high1=min(2*W-b[i],2*H+b[i]);
			for(int j=i+1;j<=m;j++)
			{
				low2=max(b[j],-b[j]);
				high2=min(2*W-b[j],2*H+b[j]);
				low2=max(low2,low1);
				high2=min(high2,high1);
				l=lower_bound(a+1,a+1+n,low2)-a;
				r=upper_bound(a+1,a+1+n,high2)-a-1;
				if(r>l)
					re=(re+(r-l+1)*(r-l)/2)%MOD;
			}
		}
		printf("%lld\n",re);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xiji333/article/details/89294466