题目真坑。。。。。。。。明显不可能会出现-1的情况嘛
离散化+树状数组
x,y坐标分别排序,扫一遍,找出所有的横线和竖线,统计出横线、竖线上端点、竖线下端点。
对统计出的数据进行排序,关键字为y,当y值相同时,下端点优先于横线优先于上端点。
从上往下依次扫描,扫到横线时统计横线左右端点内(开区间)的竖线数量,扫到竖线上端点时竖线数量+1,扫到下端点时竖线数量-1(上边的优先级因此确立)。
最后由于没有统计原先存在的黑点,再加上即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+5;
struct Node{
int x,y;
}a[N];
struct Segment{
int l,r,y,k; //k=0 横线,k=1 竖线上端点,k=-1 竖线下端点
}s[N*3];
int hash[N],tr[N],n,cnt,ans;
int gethash(int x){
return lower_bound(hash+1,hash+1+n,x)-hash;
}
bool cmp1(Node a,Node b){ //横线统计
if(a.y!=b.y)return a.y<b.y;
return a.x<b.x;
}
bool cmp2(Node a,Node b){ //竖线统计
if(a.x!=b.x)return a.x<b.x;
return a.y<b.y;
}
bool cmp3(Segment a,Segment b){
if(a.y!=b.y)return a.y<b.y;
return a.k<b.k;
}
void pre(){
sort(a+1,a+1+n,cmp1);
for(int i=2;i<=n;i++)
if(a[i].y==a[i-1].y){
s[++cnt].l=gethash(a[i-1].x);s[cnt].r=gethash(a[i].x);s[cnt].y=a[i].y;s[cnt].k=0;
}
sort(a+1,a+1+n,cmp2);
for(int i=2;i<=n;i++)
if(a[i].x==a[i-1].x){
int tmp=gethash(a[i].x);
s[++cnt].y=a[i-1].y;s[cnt].l=tmp;s[cnt].k=1;
s[++cnt].y=a[i].y;s[cnt].l=tmp;s[cnt].k=-1;
}
}
inline int lowbit(int x){return x&-x;}
void add(int x,int v){
for(;x<=n;x+=lowbit(x))tr[x]+=v;
}
int sum(int x){
int ret=0;
for(;x>0;x-=lowbit(x))ret+=tr[x];
return ret;
}
void go(){
for(int i=1;i<=cnt;i++)
if(s[i].k)add(s[i].l,s[i].k);
else ans+=sum(s[i].r-1)-sum(s[i].l);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
hash[i]=a[i].x;
}
sort(hash+1,hash+1+n);
pre();
sort(s+1,s+1+cnt,cmp3);
go();
printf("%d",ans+n);
return 0;
}