题解 SP58 【PICAD - Crime at Piccadily Circus】

题意分析

总共有 \(10\) 组数据,你应该在最外圈套个 \(10\) 次的循环!!!!!

在每组数据中,有案件可能的时间段,所有区间都是左闭右闭的,还有犯罪嫌疑人可能在的时间区间。

要统计同一时间(这个时间必须在案件发生时间段内)在的人数的最大值与最小值,这里将其离散化后用差分解决。

代码实现

set<int>S;
map<int,int>mp;
set<int>::iterator it;

因为懒,所以用 \(set\)\(map\) 来离散。这两个数据结构不用说了吧。

S.insert(L); S.insert(R);
for(int i=1;i<=N;i++) fin>>A[i].l>>A[i].r, S.insert(A[i].l), S.insert(A[i].r);
for(it=S.begin();it!=S.end();it++) mp[*it]=++cnt;

这就是离散的具体过程了。

在处理差分之前,先来看看这么一组数据

1 2
2
1 1
2 2

这组数据的正确结果应该是 \(0\) \(1\),因为当时间为 \(1.5\) 时是没有任何一个人在现场的,时间戳可以是浮点数

L=mp[L]; R=mp[R]; memset(X,0,sizeof X); memset(I,0,sizeof I); cnt++;
for(int i=1;i<=N;i++) X[mp[A[i].l]]++, X[mp[A[i].r]+1]--, I[mp[A[i].l]]++, I[mp[A[i].r]]--;
for(int i=1;i<=cnt;i++){
	X[i]+=X[i-1]; I[i]+=I[i-1]; if(i>R) break; 
	if(L<=i){
		maxx=max(maxx,X[i]);
		if(i!=R) minn=min(minn,I[i]);
	}
}

这一块代码是差分,开了两个数组,\(X\) 数组用来刷最大值,\(I\) 数组用来刷最小值,这里注意一下啊,当 \(i=N\) 的时候是不能刷最小值的,因为会扩展到错误的值,因为在 \(K\) 个元素的区间内,实际可用 \(min\) 值只有 \(K-1\) 个。

到这里,这道题就解完了,完整代码不贴了,相信看到这里就能够解掉这道题。

Made By \(\operatorname{wheneveright}\).

posted @ 2021-04-12 19:06  XJ21  阅读(116)  评论(0)    收藏  举报