题意:给定n个区间,要使每个区间内至少有两个数字被选中,共需要选出多少个不同的数字。
分析:按区间结束点从小到大排序,从左到右看每个区间内是否已有两个数被选出,若不够则选该区间最后的数字填补。
利用树状数组统计该区间已被选中了多少数字。
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
usingnamespace std;
#define maxn 10005
struct Interval
{
int s, e;
} interval[maxn];
int n, ar[maxn];
booloperator<(const Interval &a, const Interval &b)
{
if (a.e == b.e)
return a.s < b.s;
return a.e < b.e;
}
int lowb(int t)
{
return t & (-t);
}
void add(int i, int v)
{
for (; i < maxn; ar[i] += v, i += lowb(i))
;
}
int sum(int i)
{
int s =0;
for (; i >0; s += ar[i], i -= lowb(i))
;
return s;
}
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d", &n);
for (int i =0; i < n; i++)
{
scanf("%d%d", &interval[i].s, &interval[i].e);
interval[i].s++;
interval[i].e++;
}
sort(interval, interval + n);
for (int i =0; i < n; i++)
{
int num = sum(interval[i].e) - sum(interval[i].s -1);
//cout << interval[i].e << " " << num << endl;
for (int j =0; j <2- num; j++)
add(interval[i].e - j, 1);
}
printf("%d\n", sum(interval[n -1].e));
return0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
usingnamespace std;
#define maxn 10005
struct Interval
{
int s, e;
} interval[maxn];
int n, ar[maxn];
booloperator<(const Interval &a, const Interval &b)
{
if (a.e == b.e)
return a.s < b.s;
return a.e < b.e;
}
int lowb(int t)
{
return t & (-t);
}
void add(int i, int v)
{
for (; i < maxn; ar[i] += v, i += lowb(i))
;
}
int sum(int i)
{
int s =0;
for (; i >0; s += ar[i], i -= lowb(i))
;
return s;
}
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d", &n);
for (int i =0; i < n; i++)
{
scanf("%d%d", &interval[i].s, &interval[i].e);
interval[i].s++;
interval[i].e++;
}
sort(interval, interval + n);
for (int i =0; i < n; i++)
{
int num = sum(interval[i].e) - sum(interval[i].s -1);
//cout << interval[i].e << " " << num << endl;
for (int j =0; j <2- num; j++)
add(interval[i].e - j, 1);
}
printf("%d\n", sum(interval[n -1].e));
return0;
}