中午1点到晚上7点,终于把你丫的做出来了!
开始是有思路的,半小时写完后用3分钟证明了自己的错误性。。。
于是重头再来。。第二遍写的时候在updata()里面绕了很久很久。。
最后写完提交发现MLE。。才发现这颗线段树这么大。。
在POJ上看评论提示说要用离散化。。于是无耻的去看了别人的代码。。
改进之后终于AC了。。。
题目大意:一块长度未知的宣传墙,N个人往上面贴海报,给定每个海报的起点与终点。求所有海报贴完后能被看到的海报数目。(被截断的两半算一张)
思路:用线段树可以解决,但是由于每个海报的起点与终点的取值范围是1e7,所以需要使用离散化。。
来来来:做个笔记撒~终于找到为何当初苦苦报错的原因了。。原来是因为cmp返回值原因导致端点从大到小排序。。从而最大的端点(一定是线段右端)先被离散化!又存进了节点的second属性。。导致second>first。。。。so。。。。
昨天改了cmp还AC让我想了好久。。。呜呜~~
#include<stdio.h>
#include<iostream>
#include<math.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define MAX_N 10005
#define MAX_I 20005
bool ID[MAX_N];
pair<int ,int> source[MAX_N];
struct P
{
int fr; //表示端点
int li; //表示所在的线
};
P point[MAX_N<<1]; //接收数据
bool cmp(const P a,const P b) //重写sort方法
{
return a.fr<b.fr;
}
int ans;
struct node
{
int l;
int r;
int id;
}tree[MAX_I<<2];
void build(int l,int r,int dex)
{
tree[dex].l=l;
tree[dex].r=r;
tree[dex].id=0;
if(l==r) return;
build(l,(l+r)/2,dex<<1);
build((l+r)/2+1,r,(dex<<1)+1);
return;
}
void updata(int l,int r,int dex,int id)
{
if(l==tree[dex].l&&r==tree[dex].r)
{
tree[dex].id=id;
return;
}
int m=(tree[dex].l+tree[dex].r)/2;
if(m<l)
{
updata(l,r,(dex<<1)+1,id);
//updata(tree[dex].l,l-1,dex,tree[dex].id);
if(tree[dex].id!=0)
{
tree[dex<<1].id=tree[dex].id;
if(m+1<l)
updata(m+1,l-1,(dex<<1)+1,tree[dex].id);
if(r+1<=tree[dex].r)
updata(r+1,tree[dex].r,(dex<<1)+1,tree[dex].id);
tree[dex].id=0;
}
}
else if(r<=m)
{
updata(l,r,dex<<1,id);
//updata(r+1,tree[dex].r,dex,tree[dex].id);
if(tree[dex].id!=0)
{
tree[(dex<<1)+1].id=tree[dex].id;
if(r<m)
updata(r+1,m,dex<<1,tree[dex].id);
if(l>tree[dex].l)
updata(tree[dex].l,l-1,dex<<1,tree[dex].id);
tree[dex].id=0;
}
}
else
{
updata(l,m,dex<<1,id);
updata(m+1,r,(dex<<1)+1,id);
if(tree[dex].id!=0)
{
if(r+1<=tree[dex].r)
updata(r+1,tree[dex].r,(dex<<1)+1,tree[dex].id);
if(l>tree[dex].l)
updata(tree[dex].l,l-1,dex<<1,tree[dex].id);
tree[dex].id=0;
}
}
}
void query(int dex)
{
if(tree[dex].id!=0)
{
if(ID[tree[dex].id]==0)
ans++;
ID[tree[dex].id]=1;
return;
}
query(dex<<1);
query((dex<<1)+1);
}
int main()
{
int c,n,range,l,r;
scanf("%d",&c);
while(c--)
{
scanf("%d",&n);
memset(ID,0,MAX_N);
//数据离散化
for(int i=1;i<=n;i++)
{
scanf("%d%d",&l,&r);
point[(i<<1)-1].fr=l;
point[(i<<1)-1].li=i;
point[i<<1].fr=r;
point[i<<1].li=-i;
}
sort(point+1,point+n*2+1,cmp);
int temp=point[1].fr;
range=1;
for(int i=1;i<=2*n;i++)
{
if(point[i].fr!=temp)
{
range++;
temp=point[i].fr;
}
if(point[i].li<0)
source[-point[i].li].second=range;
else
source[point[i].li].first=range;
}
//for(int i=1;i<=n;i++)
// printf("%d %d\n",source[i].first,source[i].second);
build(1,range,1);
for(int i=1;i<=n;i++)
updata(source[i].first,source[i].second,1,i);
ID[0]=1;
ans=0;
query(1);
printf("%d\n",ans);
}
return 0;
}