BZOJ P1818 [Cqoi2010]内部白点【离散化】【树状数组】

扫描线。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=3e5+5;

ll n,m,ans,cnt,cnt1,cnt2,a[N];

struct node1 {
	ll x,y;
}p[N];

struct node2 {
	ll f,l,r,y;
}line[N];

struct node3 {
	ll c[N];
	void update(ll x,ll y) {
		for(;x<=N;x+=x&(-x)) c[x]+=y;
	}
	
	ll getsum(ll x) {
		ll ret=0;
		for(;x;x-=x&(-x)) ret+=c[x];
		return ret;
	}
}bit;

inline ll read() {
    ll x=0;char ch=getchar();bool f=0;
    while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return f?-x:x;
}

ll find(ll x) {	return lower_bound(a+1,a+1+cnt1,x)-a;}

bool cmp1(node1 p,node1 q) { return p.x==q.x?p.y<q.y:p.x<q.x;}

bool cmp2(node1 p,node1 q) { return p.y==q.y?p.x<q.x:p.y<q.y;}

bool cmp3(node2 p,node2 q) { return p.y==q.y?p.f>q.f:p.y<q.y;}

int main() {
	n=read();
	rep(i,1,n) {
		p[++cnt].x=read(),p[cnt].y=read();
		a[++cnt1]=p[i].x,a[++cnt1]=p[i].y;
	}

	sort(a+1,a+1+cnt1);cnt1=unique(a+1,a+1+cnt1)-a-1;
	
	sort(p+1,p+1+cnt,cmp1);
	rep(i,2,cnt) if(p[i-1].x==p[i].x) {
		ll hash=find(p[i].x);
		
		++cnt2;
		line[cnt2].l=line[cnt2].r=hash;
		line[cnt2].y=find(p[i-1].y),line[cnt2].f=1;
		
		++cnt2;
		line[cnt2].l=line[cnt2].r=hash;
		line[cnt2].y=find(p[i].y),line[cnt2].f=-1;
	}

	sort(p+1,p+1+cnt,cmp2);
	rep(i,2,cnt) if(p[i-1].y==p[i].y) {
		++cnt2;
		line[cnt2].l=find(p[i-1].x);
		line[cnt2].r=find(p[i].x);
		line[cnt2].y=find(p[i].y);
		line[cnt2].f=0;
	}
	
	sort(line+1,line+1+cnt2,cmp3);
	rep(i,1,cnt2) {
		if(line[i].f) bit.update(line[i].l,line[i].f);
		else ans+=bit.getsum(line[i].r-1)-bit.getsum(line[i].l);
	}
	
	printf("%lld",ans+n);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/82763504