The Union of k-Segments 差分思想

原题:https://vjudge.net/problem/CodeForces-612D/origin

参考题解:https://www.cnblogs.com/valk3/p/12773275.html

题目大意:x轴上有n个线段区间 问重复k次的区间有几个分别是哪些

 

错误思路:

差分。对于线段l到r, 用数组a记录。a[l]++, a[r]--。(离散化)最后得出结果的时候遍历,sum加上a的值得到当前的重复次数,判断是否大于等于k次。

错误原因:

线段可能是点,如果为点p, a[p]++, a[p]--。最后sum读a数组的时候并不能识别这个点的存在。

 

正确思路:

差分。但是把每一次的差分操作保留。比如线段l到r,对于l点上的+1操作和r点上的-1操作分别用结构体记录下来。最后遍历的时候以点位子为第一关键字,优先+1操作进行遍历。

这样就可以读到点。

 

完整代码:

 1 #include "iostream"
 2 #include "vector"
 3 #include "algorithm"
 4 using namespace std;
 5 typedef long long ll;
 6 const ll mx=2e6+10;
 7 typedef struct NODE{
 8     ll pos, v;
 9     NODE(){}
10     NODE(ll pos, ll v):pos(pos), v(v){}
11     bool operator <(const NODE b)const{
12         if(pos==b.pos) return v>b.v;
13         return pos<b.pos;
14     }
15 }NODE;
16 NODE nos[mx];
17 
18 int main() {
19     ll n, k, tot=0;
20     scanf("%lld %lld", &n, &k);
21     for(ll i=1;i<=n;i++){
22         ll l, r;
23         scanf("%lld %lld", &l, &r);
24         nos[++tot]=NODE(l, 1);
25         nos[++tot]=NODE(r, -1);
26     }
27     sort(nos+1, nos+1+tot);
28     
29     
30     ll sum=0, f=0;
31     ll fir;//记录每个满足条件区段的第一个pos
32     vector<pair<ll, ll> >v;
33     for(ll i=1;i<=tot;i++){
34         sum+=nos[i].v;//读取当前的value
35         if(sum==k&&f==0){
36             fir=nos[i].pos;
37             f=1;
38         }
39         else if(sum<k&&f==1){
40             v.emplace_back(fir, nos[i].pos);
41             f=0;
42         }
43     }
44     //输出结果
45     printf("%d\n", v.size());
46     for(auto it:v){
47         printf("%lld %lld\n", it.first, it.second);
48     }
49 
50     return 0;
51 }

 

posted @ 2020-10-06 23:55  反射狐  阅读(172)  评论(0)    收藏  举报