您的位置:首页 > 其它

hiho一下 第二十一周 离散化与线段树回顾

2014-11-24 16:04 330 查看
题意:

有n(<=10^5)个线段 ,每个线段[li,ri]的范围<=10^9。现在按顺序 将线段一个个放在线上,问最终能看到几个线段(有任何一块露出都是看到)

题解:

那么久离散10^9到10^5了...记得以前做过差不多的..这次还碰到问题了..比如:

3 10

1 4

1 1

3 4

直接离散化出1,3,4来做之后发现答案不对..因为对于第一个线段..存在[2,2]的区域是看得见的..但是离散化后不能体现出来了。所以这次做的处理是读入坐标时将其左界-1与右界+1也放到离散数列里面。

Program:

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<map>
#include<string>
#include<string.h>
#include<algorithm>
#define MAXN 400005
#define oo 1000000007
#define ll long long
using namespace std;   
int P[MAXN][2],id[MAXN],T[MAXN<<2],col[MAXN<<2];
bool F[MAXN];
int find(int d,int n)
{
       int l=0,r=n+1,mid;
       while (r-l>1)
       {
               mid=l+r>>1;
               if (id[mid]<=d) l=mid;
                          else r=mid;
       }
       return l;
} 
void PushDown(int x)
{
       if (!col[x]) return;
       T[x<<1]=T[x<<1|1]=col[x];
       col[x<<1]=col[x<<1|1]=col[x];
       col[x]=0;
}
void Update(int l,int r,int L,int R,int d,int x)
{
       if (l>=L && r<=R)
       {
               T[x]=col[x]=d;
               return;
       }
       PushDown(x);
       int mid=l+r>>1;
       if (mid>=L) Update(l,mid,L,R,d,x<<1);
       if (mid<R)  Update(mid+1,r,L,R,d,x<<1|1);
}  
int Query(int l,int r,int p,int x)
{
       if (l==r) return T[x];
       PushDown(x);
       int mid=l+r>>1;
       if (mid>=p) return Query(l,mid,p,x<<1);
             else  return Query(mid+1,r,p,x<<1|1);
}
int main() 
{      
       int num,m,n,l,r,i,x,ans; 
       scanf("%d%d",&num,&m),n=0;
       for (i=1;i<=num;i++) 
          scanf("%d%d",&P[i][0],&P[i][1]),
          id[++n]=P[i][0],id[++n]=P[i][1],
          id[++n]=P[i][0]-1,id[++n]=P[i][1]+1;
       sort(id+1,id+1+n);
       memset(T,0,sizeof(T));
       memset(col,0,sizeof(col));
       for (i=1;i<=num;i++) 
          P[i][0]=find(P[i][0],n),
          P[i][1]=find(P[i][1],n);
       for (i=1;i<=num;i++) Update(1,n,P[i][0],P[i][1],i,1);  
       memset(F,false,sizeof(F)),F[0]=true,ans=0;
       for (i=1;i<=n;i++)
       {
               x=Query(1,n,i,1);
               if (!F[x]) ans++,F[x]=true;
       }
       printf("%d\n",ans);
       return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: