Codeforces Round #665 (Div. 2) E. Divide Square

题意:1e6*1e6的坐标系,给一堆水平和垂直的线,问分割的区域个数

保证线一定和边界有交点,且同一个x/y只有一条线

交点数+完全切割线数+1即为ans

求交点就是经典的扫描线了,用了树状数组

#include<bits/stdc++.h>

using namespace std;

inline int rd(){
	int ret=0,f=1;char c;
	while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
	return ret*f;
}
#define pc putchar
#define space() pc(' ')
#define nextline() pc('\n')
void pot(int x){if(!x)return;pot(x/10);pc('0'+x%10);}
void out(int x){if(!x)pc('0');if(x<0)pc('-'),x=-x;pot(x);}

const int UP = 1000000;
const int MAXN = 1000005;
int t[MAXN];
void modify(int x,int y){
	while(x<MAXN){t[x]+=y;x+=(x&-x);}
}
int query(int x){
	int ret=0;
	while(x){ret+=t[x];x-=x&-x;}
	return ret;	
}

struct Node{
	int x,y,w;
	bool operator < (const Node &rhs) const {
		return x < rhs.x;
	}
	Node(int xx=0,int yy=0,int ww=0){x=xx;y=yy;w=ww;}
}node[MAXN];

struct Line{
	int x,l,r;
	bool operator < (const Line &rhs) const{
		return x<rhs.x;
	}
	Line(int xx=0,int ll=0,int rr=0){x=xx;l=ll;r=rr;}
}line[MAXN];

int n,m,num;
long long ans;

int main(){
	n=rd();m=rd();
	int y,l,r;
	for(int i=1;i<=n;i++){
		y=rd();l=rd();r=rd();
		if(l==0&&r==UP) ans++;
		node[++num]=Node(l,y,1);
		node[++num]=Node(r+1,y,-1);
	}
	for(int i=1;i<=m;i++){
		line[i].x = rd();
		line[i].l = rd();
		line[i].r = rd();
		if(line[i].l==0&&line[i].r==UP) ans++;	
	}
	sort(line+1,line+1+m);
	sort(node+1,node+1+num);
	for(int i=1,j=0;i<=m;i++){
		while(j<(n<<1)&&node[j+1].x <= line[i].x){
			j++;
			modify(node[j].y+1,node[j].w);
		}
		ans+=query(line[i].r+1)-query(line[i].l);
	}
	cout<<ans+1;
	return 0;
}

posted @ 2020-08-23 17:33  GhostCai  阅读(84)  评论(0编辑  收藏  举报