http://acm.hdu.edu.cn/showproblem.php?pid=5124
题意:区间覆盖次数问题。
解题思路:线段树水之。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100005;
struct Node
{
int x,y;
}p[maxn];
struct Seg
{
int l,r,Max,lazy;
}tree[maxn<<2];
int n,tot,cnt,tmp[maxn<<1],order[maxn];
void build(int rt,int l,int r)
{
tree[rt].l = l, tree[rt].r = r;
tree[rt].Max = 0,tree[rt].lazy = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
}
void PushDown(int rt)
{
if(tree[rt].lazy)
{
tree[rt<<1].lazy += tree[rt].lazy;
tree[rt<<1].Max += tree[rt].lazy;
tree[rt<<1|1].lazy += tree[rt].lazy;
tree[rt<<1|1].Max += tree[rt].lazy;
tree[rt].lazy = 0;
}
}
void update(int rt,int l,int r)
{
if(l <= tree[rt].l && tree[rt].r <= r)
{
tree[rt].Max++;
tree[rt].lazy++;
return;
}
PushDown(rt);
int mid = (tree[rt].l + tree[rt].r) >> 1;
if(l <= mid) update(rt<<1,l,r);
if(mid < r) update(rt<<1|1,l,r);
tree[rt].Max = max(tree[rt<<1].Max,tree[rt<<1|1].Max);
}
int bisearch(int k)
{
int l = 1, r = cnt, mid;
while(l <= r)
{
mid = (l + r) >> 1;
if(order[mid] == k) return mid;
else if(order[mid] < k)
l = mid + 1;
else r = mid - 1;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
tot = cnt = 0;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
tmp[tot++] = p[i].x;
tmp[tot++] = p[i].y;
}
sort(tmp,tmp+tot);
order[++cnt] = tmp[0];
for(int i = 1; i < tot; i++)
if(tmp[i] != tmp[i-1])
order[++cnt] = tmp[i];
build(1,1,cnt);
for(int i = 1; i <= n; i++)
{
int l = bisearch(p[i].x);
int r = bisearch(p[i].y);
update(1,l,r);
}
printf("%d\n",tree[1].Max);
}
return 0;
}