题目真坑。。。。。。。。明显不可能会出现-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; }