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 }