题解 [ABC221D] Online games
Update on 2023.6.9 15:58:发现有几个错别字,已改正。
大家好,我是 CQ-C2024 蒟蒻 CJH。
题意
给定 $n$ 个区间,第 $i$ 个区间的范围是 $[A_i,A_i+B_i)$。
设 $D_k$ 为有 $k$ 个区间覆盖的长度,请你求出 $\forall k \in [1,n],D_k$。
分析
其实这一道题大可不必使用离散化(虽然我有很多同学都用了),其实只需要在 map 上差分就可以了!
知道了这一点,其实就并不难了。
时间复杂度 $O(n \log n)$,其中 $O(\log n)$ 为 map 所占用的时间复杂度。
代码
//the code is from chenjh
#include<cstdio>
#include<map>
int n;
std::map<int,int> M;//有多少人登录。
int d[200002];
int main(){
scanf("%d",&n);
for(int i=0,a,b;i<n;i++){
scanf("%d%d",&a,&b);
++M[a],--M[a+b];//进行差分。注意是左闭右开,所以右边不需要再加一。
}
int lt=0;//记录上一个节点的值。
for(auto it=M.begin();it!=M.end();++it) it->second+=lt,lt=it->second;//还原差分。
for(auto it=M.begin(),nx=++M.begin();nx!=M.end();it=nx,++nx) d[it->second]+=(nx->first)-(it->first);
/*
两个迭代器,it 为当前迭代器,nx 为下一个的迭代器。
所以只需要给当前的人数对应的答案加上下一次迭代器的时间减去当前迭代器的时间即可。
*/
for(int i=1;i<=n;i++) printf("%d ",d[i]);
return 0;
}

浙公网安备 33010602011771号