题意很好理解:给定一些线段的左右端点,问至少被覆盖了k次的线段有几个,并从左到右一一列出
其实就是一个扫描线,从最左边的端点开始扫描,每遇到线段的左端点就+1,每遇到线段的右端点就-1.只是有一处需要注意,那就是一个点可能既是左端点又是右端点,此时需要先将其设为左端点,每次+1都记录,直到它不是左端点之后再视为右端点-1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int>P;
const int N = 1e6 + 5;
int po[2*N];
map<int ,int>mp1, mp2;
vector<P>rec;
int main()
{
int n, k, x, y;
scanf("%d%d", &n, &k);
int cnt = 0;
for(int i = 0; i < n; i++)
{
scanf("%d%d", &x, &y);
po[cnt++] = x;
po[cnt++] = y;
if(!mp1.count(x))
mp1.insert(P(x, 1));
else mp1[x]++;
if(!mp2.count(y))
mp2.insert(P(y, 1));
else mp2[y]++;
}
sort(po, po + cnt);
int ans = 0, beg, cnt1 = 0;
bool ju = false;
for(int i = 0; i < cnt; i++)
{
int tp = po[i];
if(mp1.count(tp) && !mp2.count(tp))
ans++;
else if(!mp1.count(tp) && mp2.count(tp))
ans--;
else if(mp1.count(tp) && mp2.count(tp))
{
if(mp1[tp] != 0)
{
ans++;
mp1[tp]--;
}
else
{
ans--;
}
}
if(!ju && ans == k)
{
beg = tp;
ju = true;
}
else if(ju && ans < k)
{
rec.push_back(P(beg, tp));
ju = false;
cnt1++;
}
}
printf("%d\n", cnt1);
int siz = rec.size();
for(int i = 0; i < siz; i++)
{
printf("%d %d\n", rec[i].first, rec[i].second);
}
}