BZOJ 1818 Cqoi2010 内部白点 树状数组

来源:互联网 发布:电商网站 知乎 编辑:程序博客网 时间:2024/06/08 17:38

题目大意:给定平面上的一些黑点,其它位置都是白点,一个白点如果上下左右都有黑点就会变成黑点,求最终会有多少个黑点

语文题?

总之我们现在得到了一些横向和纵向的线段(注意线段不能包含两端点!),求出交点数后+n就是答案

我们可以将横向线段看做修改,纵向线段看做询问,那么一个询问可以拆成两个

然后我们离线做,将询问按y坐标排序,对于每个询问将y坐标小于等于这个询问的修改都加入树状数组,然后查询这个询问的x坐标即可

懒得离散化,第一次尝试用Hash表写树状数组,效果还不错= =

时间复杂度O(nlogn)

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 100100using namespace std;struct Point{int x,y;friend istream& operator >> (istream &_,Point &p){scanf("%d%d",&p.x,&p.y);p.x+=1000000007;p.y+=1000000007;return _;}}points[M];struct Interval{int l,r,y;Interval() {}Interval(int _,int __,int ___):l(_),r(__),y(___) {}bool operator < (const Interval &i) const{return y < i.y;}}intervals[M],*I=intervals;struct Query:Point{int flag;Query() {}Query(int _,int __,int ___):flag(___){x=_;y=__;}}queries[M<<1],*Q=queries;int n;long long ans;bool Compare1(const Point &p1,const Point &p2){if(p1.x!=p2.x)return p1.x<p2.x;return p1.y<p2.y;}bool Compare2(const Point &p1,const Point &p2){if(p1.y!=p2.y)return p1.y<p2.y;return p1.x<p2.x;}namespace BIT{struct Hash_Set{struct List{int hash,val;List *next;List(int _,List *__):hash(_),val(0),next(__){}}*head[1001001];int& operator [] (int hash){int pos=hash%1001001;List *temp;for(temp=head[pos];temp;temp=temp->next)if(temp->hash==hash)return temp->val;return (head[pos]=new List(hash,head[pos]))->val;}}c;void Update(int x,int y){for(;x;x-=x&-x)c[x]+=y;}int Get_Ans(long long x){int re=0;for(;x<=2000000007;x+=x&-x)re+=c[x];return re;}}int main(){using namespace BIT;int i;cin>>n;for(i=1;i<=n;i++)cin>>points[i];sort(points+1,points+n+1,Compare2);for(i=2;i<=n;i++)if(points[i].y==points[i-1].y&&points[i].x>=points[i-1].x+2)new (I++)Interval(points[i-1].x+1,points[i].x-1,points[i].y);sort(points+1,points+n+1,Compare1);for(i=2;i<=n;i++)if(points[i].x==points[i-1].x&&points[i].y>=points[i-1].y+2){new (Q++)Query(points[i].x,points[i-1].y,-1);new (Q++)Query(points[i].x,points[i].y-1,1);}sort(intervals,I);sort(queries,Q,Compare2);Interval *_i=intervals;Query *_q=queries;for(;_q<Q;_q++){for(;_i<I&&_i->y<=_q->y;_i++)Update(_i->l-1,-1),Update(_i->r,1);ans+=Get_Ans(_q->x)*_q->flag;}cout<<ans+n<<endl;return 0;}


0 0
原创粉丝点击