1818: [Cqoi2010]内部白点

来源:互联网 发布:石家庄seo建站 编辑:程序博客网 时间:2024/06/08 01:24

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


0 0
原创粉丝点击