题目链接:http://poj.org/problem?id=2528
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 43201 | Accepted: 12591 | 
Description
Input
Output

Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
Source
今天又把这道题做了一遍~离散化参考自http://www.cnblogs.com/vongang/archive/2011/08/10/2133869.html思路:典型的线段树,区间更新,然后递归查询即可,但是这题输入的数据 1 <= li <= ri <= 10000000.
数据太大,直接建树肯定会MLE,所以离散化一下,也就是将2*n个数映射在1~2*n之间~~~
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
const int N=20000+100;
using namespace std;
int cnt;
struct node
{
 int l,r,cover;
}st[N*4];
struct  node1
{
  int num; // 存放端点的值
  int id;  // 存放端点的位置
}po[N*2];
bool cmp(node1 a,node1 b)
{
 return a.num<b.num;
}
int f[N][2],flag[N];
void build(int v,int l,int r)
{
 st[v].l=l;
 st[v].r=r;
 st[v].cover=0;
 if(l==r)return;
 int mid=(l+r)/2;
 build(2*v,l,mid);
 build(2*v+1,mid+1,r);
}
void update(int v,int l,int r,int d)
{
  if(st[v].l==l&&st[v].r==r)
  {
    st[v].cover=d;
    return;
  }
  if(st[v].cover>0)
  {
    st[2*v].cover=st[v].cover;
    st[2*v+1].cover=st[v].cover;
    st[v].cover=0;
  }
  int mid=(st[v].l+st[v].r)/2;
  if(r<=mid)update(2*v,l,r,d);
  else if(l>mid)update(2*v+1,l,r,d);
  else
  {
    update(2*v,l,mid,d);
    update(2*v+1,mid+1,r,d);
  }
}
void getsum(int v)
{
 if(st[v].cover)
 {
   if(!flag[st[v].cover])
   {
    cnt++;
    flag[st[v].cover]=1;
   }
   return;
 }
 getsum(2*v);
 getsum(2*v+1);
}
int main()
{
  int T,n;
  cin>>T;
  while(T--)
  {
   scanf("%d",&n);
   memset(f,0,sizeof(f));
   memset(flag,0,sizeof(flag));
   for(int i=1;i<=n;i++)
   {
     scanf("%d%d",&f[i][0],&f[i][1]);
     po[2*i-1].num=f[i][0];//左端点的值
     po[2*i-1].id=i;  //标记为左端点
     po[2*i].num=f[i][1]; //右端点的值
     po[2*i].id=-1*i; //标记为右端点
   }
   sort(po+1,po+1+2*n,cmp);
   int t=1,temp=po[1].num;
   for(int i=1;i<=2*n;i++)
   {
      if(temp!=po[i].num)
      {
        t++;
        temp=po[i].num;
      }
      if(po[i].id>0)
        f[po[i].id][0]=t;
      else
        f[-1*po[i].id][1]=t;
   }
  build(1,1,t);
   for(int i=1;i<=n;i++)
   {
     update(1,f[i][0],f[i][1],i);
   }
   cnt=0;
   getsum(1);
   printf("%d\n",cnt);
  }
  return 0;
}
原文地址:http://blog.csdn.net/liusuangeng/article/details/39524335