阴间扫描线

指针线段树太容易\(RE\)了吧
\(Windows\)评测下编译不出来
我真吐了

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

#define int long long 

const int p=1e6+5;

template<typename _T>
void read(_T &x)
{
	x=0;char s=getchar();int f=1;
	while(s>'9'||s<'0'){f=1;if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<1)+(x<<3)+s-'0';s=getchar();}
	x*=f;
}

struct line{
	int l,r;
	int h;
	int mark;
	line(int a,int b,int c,int d):l(a),r(b),h(c),mark(d){};
	line(){};
};
line sline[p<<1];
int xx[p<<1];

inline bool cmp(line a,line b)
{
	return a.h<b.h;
}

struct segment{
	int l;
	int r;
	int mark;
	int len;
	segment *ls,*rs;
	
	inline bool inrange(int L,int R){return L<=xx[l]&&xx[r+1]<=R;}
	inline bool outofrange(int L,int R){return xx[r+1]<=L||R<=xx[l];}
	
	void pushup()
	{
		if(mark){len = xx[r+1]-xx[l];}
		else
		{
			if(ls==NULL) len = 0;//记得特判
			else
			len = ls->len + rs->len;
		}
	}
	
	void change(int L,int R,int m)
	{
		if(inrange(L,R))
		{
			mark+=m;
			pushup();
		}
		else
		{
			if(!outofrange(L,R))
			{			
			ls->change(L,R,m);
			rs->change(L,R,m);
			pushup();							
			}
		}
	}
	
};
segment mem[p<<2],*pool = mem,*rot;
segment *New(){return ++pool;}

segment *build(int L,int R)
{
	segment *u = New();
	u->len=0;
	u->mark=0;
	u->l = L;
	u->r = R;
	if(L == R) 
	{
		u->ls=NULL;
		u->rs=NULL;//一定记着打上NULL,不然直接暴毙
		return u;
	}
	
	
	int mid = (L+R)>>1;
	u->ls = build(L,mid);
	u->rs = build(mid+1,R);		
	
	return u;//Linux下不返回会RE
}

signed main()
{	
	int n;
	
	read(n);
	for(int i=1,x1,x2,y1,y2;i<=n;i++)
	{
		read(x1);read(y1);read(x2);read(y2);
		xx[i] = x1;xx[i+n] = x2;
		sline[i] = line (x1,x2,y1,1);
		sline[n+i] = line (x1,x2,y2,-1);
	}
	
	sort(sline+1,sline+1+2*n,cmp);
	sort(xx+1,xx+1+2*n);
	
	int tot = unique(xx+1,xx+1+2*n)-xx-1;
	
	rot = build(1,tot-1);
	
	int sum = 0;
	
	for(int i=1;i<n*2;i++)
	{
		rot->change(sline[i].l,sline[i].r,sline[i].mark);
		sum+=rot->len*(sline[i+1].h - sline[i].h);
		
	}
	
	cout<<sum;
}
posted @ 2020-12-01 10:27  ·Iris  阅读(112)  评论(0编辑  收藏  举报