阴间扫描线
指针线段树太容易\(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;
}