BZOJ1818 [Cqoi2010]内部白点 扫描线/线段求交

毫无头绪。。hint了一波瞄到了用扫描线做线段求交

想了想开始码。。过样例之后谜之wa

估计是加line的时候没把点做第二维排序,line不是一段一段进去的,加上就过了

//#include<bits/stdc++.h>  
#pragma comment(linker, "/STACK:1024000000,1024000000")   
#include<stdio.h>  
#include<algorithm>  
#include<queue>  
#include<string.h>  
#include<iostream>  
#include<math.h>  
#include<set>  
#include<map>  
#include<vector>  
#include<iomanip>  
using namespace std;  
#define ll long long  
#define pb push_back  
#define FOR(a) for(int i=1;i<=a;i++)  
const int inf=0x3f3f3f3f;  
 
const int maxn=2e5+5;    
 
int n,hash[maxn<<1];

struct dot{int x,y;}a[maxn];
bool cmp1(dot a,dot b){if(a.x==b.x){return a.y<b.y;}return a.x<b.x;}
bool cmp2(dot a,dot b){if(a.y==b.y){return a.x<b.x;}return a.y<b.y;}

struct Line{int x1,x2,y,kind;}line[maxn<<1];	//-1竖出1竖入,0横
bool cmp(Line a,Line b){
	if(a.y==b.y)return a.kind<b.kind;
	return a.y<b.y;
}

int sum[maxn<<2];
void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
void update(int a,int b,int c,int l,int r,int rt){
	if(l==r){sum[rt]+=c;return;}
	int m=l+r>>1;
	if(a<=m)update(a,b,c,l,m,rt<<1);
	else update(a,b,c,m+1,r,rt<<1|1);
	pushup(rt);
}
int query(int a,int b,int l,int r,int rt){
	if(a<=l&&b>=r)return sum[rt];
	int m=l+r>>1;
	int ret=0;
	if(a<=m)ret+=query(a,b,l,m,rt<<1);
	if(b> m)ret+=query(a,b,m+1,r,rt<<1|1);
	return ret;
}

int main(){
	scanf("%d",&n);
	for(int i=1,x,y;i<=n;i++){
		scanf("%d%d",&x,&y);
		a[i]=(dot){x,y};
		hash[i]=a[i].x;
	}
	sort(hash+1,hash+1+n);
	int num=1;
	for(int i=2;i<=n;i++){
		if(hash[i]!=hash[i-1])hash[++num]=hash[i];
	}

	int tot=0;
	sort(a+1,a+1+n,cmp1);
	for(int i=2;i<=n;i++){
		if(a[i].x==a[i-1].x){
			int y1=min(a[i].y,a[i-1].y);
			int y2=max(a[i].y,a[i-1].y);
			line[++tot]=(Line){a[i].x,a[i].x,y1,1};
			line[++tot]=(Line){a[i].x,a[i].x,y2,-1};
		}
	}
	sort(a+1,a+1+n,cmp2);
	for(int i=2;i<=n;i++){
		if(a[i].y==a[i-1].y){
			int x1=min(a[i].x,a[i-1].x);
			int x2=max(a[i].x,a[i-1].x);
			line[++tot]=(Line){x1,x2,a[i].y,0};
		}
	}
	sort(line+1,line+1+tot,cmp);
	int ans=0;
	for(int i=1;i<=tot;i++){
		//cout<<i<<" "<<sum[1]<<endl;
		Line now=line[i];

		if(now.kind!=0){
			int l=lower_bound(hash+1,hash+1+num,now.x1)-hash;
			if(now.kind==1)update(l,l,1,1,num,1);
			else update(l,l,-1,1,num,1);

		}else{
			int l=lower_bound(hash+1,hash+1+num,now.x1)-hash;
			int r=lower_bound(hash+1,hash+1+num,now.x2)-hash;

			if(r==l+1)continue;

			ans+=query(l+1,r-1,1,num,1);
		}
		//cout<<i<<" "<<query(2,2,1,num,1)<<endl;
	}
	printf("%d
",ans+n);
}


原文地址:https://www.cnblogs.com/Drenight/p/8611208.html