扫描线 & 矩形面积并
code on 26.7.16
点击查看代码
#include<bits/stdc++.h>
#define int long long
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
constexpr int maxn=2e6+10,p=1e9+7;
int read()
{
int x=0,f=1;
char ch=getchar();
while (ch<'0' || ch>'9')
{
if (ch == '-') f=-1;
ch=getchar();
}
while (ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*f;
}
struct _
{
int xa,xb,y,b;
bool operator < (_ a) const {return y<a.y;}
}lin[maxn];
struct __ {int l,r,sum,cnt;}tr[maxn];
int lc,cnt,n,ans,a[maxn],xa,xb,ya,yb;
void Pushup(int rt)
{
if (tr[rt].cnt) tr[rt].sum=a[tr[rt].r+1]-a[tr[rt].l];
else tr[rt].sum=tr[lson].sum+tr[rson].sum;
}
void Build(int rt,int l,int r)
{
tr[rt].l=l,tr[rt].r=r;
if (l == r) return;
int mid=(l+r) >> 1;
Build(lson,l,mid),Build(rson,mid+1,r);
}
void Upd(int rt,int l,int r,int val)
{
if (l<=tr[rt].l && tr[rt].r<=r)
{
tr[rt].cnt+=val;
Pushup(rt);
return;
}
int mid=(tr[rt].l+tr[rt].r) >> 1;
if (l<=mid) Upd(lson,l,r,val);
if (r>mid) Upd(rson,l,r,val);
Pushup(rt);
}
signed main()
{
n=read();
for (int i=1;i<=n;i++)
{
xa=read(),ya=read(),xb=read(),yb=read();
lc++;lin[lc]={xa,xb,ya,0};
lc++;lin[lc]={xa,xb,yb,1};
a[i]=xa,a[i+n]=xb;
}
sort(a+1,a+1+n*2);
cnt=unique(a+1,a+1+n*2)-a-1;
sort(lin+1,lin+1+n*2);
Build(1,1,cnt-1);
for (int i=1;i<=n*2;i++)
{
_ l=lin[i];
if (i>1) ans+=tr[1].sum*(lin[i].y-lin[i-1].y);
if (l.b)
{
int u,v;
u=lower_bound(a+1,a+1+cnt,l.xa)-a;
v=lower_bound(a+1,a+1+cnt,l.xb)-a-1;
Upd(1,u,v,-1);
}
else
{
int u,v;
u=lower_bound(a+1,a+1+cnt,l.xa)-a;
v=lower_bound(a+1,a+1+cnt,l.xb)-a-1;
Upd(1,u,v,1);
}
}
printf("%lld\n",ans);
return 0;
}
define lson (rt<<1)
define rson (rt<<1|1)
define int long long
const int N = 2e6+10;
typedef long long ll;
inline void read(int &x)//加速输入
{
char ch=getchar();int f=1;x=0;
while(!isdigit(ch) && ch^'-') ch=getchar();
if(ch=='-') f=-1,ch=getchar();
while(isdigit(ch)) x=x10+ch-'0',ch=getchar();
x=f;
}
struct smx{
int y1,y2,x,cnt;
bool aaa;
}line[N];
bool cmp(smx a,smx b){
return a.x < b.x;
}
int a[N];
struct node{
int l,r,len,cnt;
}tr[N];
void build(int rt,int l,int r){
tr[rt].l=l,tr[rt].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
}
void pushup(int rt){
if(tr[rt].cnt) tr[rt].len=a[tr[rt].r+1]-a[tr[rt].l];
else tr[rt].len = tr[lson].len + tr[rson].len;
}
void update(int rt,int l,int r,int k){
if(l<=tr[rt].l && r>=tr[rt].r) {
tr[rt].cnt+=k;
pushup(rt);
return;
}
int mid=(tr[rt].l+tr[rt].r)>>1;
if(mid>=l) update(lson,l,r,k);
if(r>mid) update(rson,l,r,k);
pushup(rt);
}
int n,ans;
signed main(){
//输入
cin >> n;
int x1,y1,x2,y2,op=0;
for(int i=1;i<=n;i++){
cin >> x1 >> y1 >> x2 >> y2;
line[++op].x = x1;
line[op].y1 = y1;
line[op].y2 = y2;
line[op].aaa = 0;
line[++op].x = x2;
line[op].y1 = y1;
line[op].y2 = y2;
line[op].aaa = 1;
a[i]=y1;
a[i+n]=y2;
}
//离散化
sort(a+1,a+1+n2);
int cnt = unique(a+1,a+1+2n)-a-1;
sort(line+1,line+1+2*n,cmp);
build(1,1,cnt);
//开始骚妙
for(int i=1;i<=n<<1;i++) {
if(i>1) ans+=tr[1].len*(line[i].x-line[i-1].x);
if(line[i].aaa) update(1,lower_bound(a+1,a+1+cnt,line[i].y1)-a,lower_bound(a+1,a+1+cnt,line[i].y2)-a-1,-1);
else update(1,lower_bound(a+1,a+1+cnt,line[i].y1)-a,lower_bound(a+1,a+1+cnt,line[i].y2)-a-1,1);
}
cout << ans;
return 0;
}
## 注
- 注释来源于老学长_2K22_

浙公网安备 33010602011771号