[2022-2-26] OICLASS-USACO提高组模拟赛 C·Convoluted Intervals S

题目链接
题面

题目描述
奶牛们正在努力尝试发明有趣的新游戏来玩。他们目前的工作之一与一组 N N N 个区间( 1 ≤ N ≤ 2 ⋅ 1 0 5 1≤N≤2⋅10^5 1N2105)有关,其中第 i i i 个区间从数轴上的 a i a_i ai 位置开始,并在位置 b i ≥ a i b_i≥a_i biai 结束。 a i a_i ai b i b_i bi 均为 0 … M 0…M 0M 范围内的整数,其中 1 ≤ M ≤ 5000 1≤M≤5000 1M5000
这个游戏的玩法是,Bessie 选择某个区间(假设是第 i i i 个区间),而她的表妹 Elsie 选择某个区间(假设是第 j j j 个区间,可能与 Bessie 所选的的区间相同)。给定某个值 k k k,如果 a i + a j ≤ k ≤ b i + b j a_i+a_j≤k≤b_i+b_j ai+ajkbi+bj,则她们获胜。
对范围 0 … 2 M 0…2M 02M 内的每个值 k k k,请计算使得 Bessie 和 Elsie 可以赢得游戏的有序对 ( i , j ) (i,j) (i,j) 的数量。
输入
输入的第一行包含 N N N M M M
以下 N N N 行每行以整数 a i a_i ai b i b_i bi 的形式描述一个区间。
输出
输出 2 M + 1 2M+1 2M+1 行,依次包含范围 0 … 2 M 0…2M 02M 中的每一个 k k k 的答案。
样例输入
2 5
1 3
2 5
样例输出
0
0
1
3
4
4
4
3
3
1
1
提示
【样例解释】
在这个例子中,对于 k = 3 k=3 k=3,有三个有序对可以使得 Bessie 和 Elsie 获胜: ( 1 , 1 ) , ( 1 , 2 ) (1,1),(1,2) (1,1)(1,2),和 ( 2 , 1 ) (2,1) (2,1)
【数据范围】
测试点 1-2 满足 N ≤ 100 , M ≤ 100 N≤100,M≤100 N100,M100
测试点 3-5 满足 N ≤ 5000 N≤5000 N5000
测试点 6-20 没有额外限制。
注意输出可能无法用 32 位整数型存储,你可能需要使用 64 位整数型(例如,C 或 C++ 中的 “long long”)。

暴力思路(10pts)

我们发现,我们只需要模拟画出一个图然后进行暴力枚举就行了。

差分+桶+加乘原理思路(100pts)

我们明显发现,这道题是可以运用差分的思想去做的,即 a i + a j a_i+a_j ai+aj 的地方加上 x i × x j x_i \times x_j xi×xj b i + b j + 1 b_i+b_j+1 bi+bj+1 的地方减去 y i × y j y_i \times y_j yi×yj

但是我们发现这样子做时间复杂度是 O ( n 2 ) O(n^2) O(n2) ,我们发现 a , b , m a,b,m a,b,m 的值域很小,可以考虑用桶存起来,时间复杂度 O ( m 2 ) O(m^2) O(m2)

AC CODE

#include<iostream>
#include<cstdio>
long long a[100005],b[100005],cnt[100005],ans;
using namespace std;
int main(){
	int n,m,x,y;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&x,&y);
		a[x]++;
		b[y]++;
	}
	for(int i=0;i<=m;i++){
		for(int j=0;j<=m;j++){
			cnt[i+j]+=a[i]*a[j],cnt[i+j+1]-=b[i]*b[j];
		}
	}
	m*=2;
	for(int i=0;i<=m;i++){
		ans+=cnt[i];
		printf("%lld\n",ans);
	}
	return 0;
}

END.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值