codeforces 1000C - Covered Points Count 【差分】

题目:戳这里

题意:给出n个线段,问被1~n个线段覆盖的点分别有多少。

解题思路:

这题很容易想到排序后维护每个端点被覆盖的线段数,关键是端点值不好处理。比较好的做法是用差分的思想,把闭区间的线段改为前闭后开,同时在求总点数的时候,也按前闭后开的区间来求,这样就巧妙避开了两个端点之间的讨论,只用维护好一个端点就行了。

代码比文字更容易理解:

 1 #include <bits/stdc++.h>
 2 #define lowbit(x) x&-x;
 3 typedef long long ll;
 4 const int maxn = 4e5+10;
 5 const int inf = 0x3f3f3f3f;
 6 const ll mod = 998244353;
 7 using namespace std;
 8 ll n;
 9 struct nod {
10     ll x;
11     int f;
12 }co[maxn];
13 ll cnt[maxn];
14 bool cmp(nod a, nod b) {
15     if(a.x == b.x) return a.f > b.f;
16     return a.x < b.x;
17 }
18 int main(){
19     ll l,r;
20     scanf("%lld", &n);
21     for(ll i = 0ll; i < n; ++i) {
22         l=2ll*i+1ll; r=2ll*i+2ll;
23         scanf("%lld %lld", &co[l].x, &co[r].x);
24         co[r].x++;//转换为前闭后开
25         co[l].f = 1;
26         co[r].f = -1;
27     }
28     int now = 1;
29     sort(co + 1, co + 1 + 2*n, cmp);
30     for(ll i = 2ll; i <= 2ll * n; ++i) {
31         cnt[now] += co[i].x - co[i-1].x;
32         now += co[i].f;
33     }
34     for(ll i = 1; i <= n; ++i) {
35         printf("%lld ", cnt[i]);
36     }
37     return 0;
38 }
View Code

 

posted @ 2018-11-21 20:28  euzmin  阅读(289)  评论(0编辑  收藏  举报