BZOJ 1818: [Cqoi2010]内部白点 扫描线+树状数组

问题转化为求每一个极长横线段与极长纵线段的交点个数. 

这个东西用扫描线+树状数组维护一下就可以了. 

code: 

#include <cstdio> 
#include <algorithm>      
#define N 200005   
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
namespace BIT 
{ 
    int C[N];  
    int lowbit(int t) { return t&(-t); }   
    void update(int x,int v) 
    {
        for(;x<N;x+=lowbit(x)) C[x]+=v;  
    }
    int query(int x) 
    {
        int tmp=0; 
        for(;x>0;x-=lowbit(x)) tmp+=C[x];  
        return tmp;   
    }
};       
struct Point 
{    
    int x,y;  
    Point(int x=0,int y=0):x(x),y(y){}   
}point[N];    
struct Line 
{ 
    int x,y,z,pri;   
    Line(int x=0,int y=0,int z=0,int pri=0):x(x),y(y),z(z),pri(pri){}  
}line[N<<1];  
bool cmpy(Point a,Point b) 
{
    return a.y==b.y?a.x<b.x:a.y<b.y;  
}
bool cmpx(Point a,Point b) 
{
    return a.x==b.x?a.y<b.y:a.x<b.x;   
}    
bool cmpl(Line a,Line b) 
{
    return a.x==b.x?a.pri<b.pri:a.x<b.x;  
} 
int A[N];   
int main() 
{
    // setIO("input");  
    int i,j,n,cnt=0,ans=0;        
    scanf("%d",&n);   
    for(i=1;i<=n;++i) 
    {  
        scanf("%d%d",&point[i].x,&point[i].y);  
        A[i]=point[i].y;          
    }   
    sort(A+1,A+1+n); 
    for(i=1;i<=n;++i) 
    {
        point[i].y=lower_bound(A+1,A+1+n,point[i].y)-A;   
    }
    sort(point+1,point+1+n,cmpy);    
    for(i=1;i<=n;i=j+1) 
    {
        j=i;  
        while(j<n&&point[j+1].y==point[i].y) ++j;    
        line[++cnt]=Line(point[i].x,point[i].y,0,1);    
        line[++cnt]=Line(point[j].x,point[j].y,0,3);           
    }   
    sort(point+1,point+1+n,cmpx);    
    for(i=1;i<=n;i=j+1)     
    {
        j=i; 
        while(j<n&&point[j+1].x==point[i].x) ++j;    
        line[++cnt]=Line(point[i].x,point[j].y,point[i].y,2);    
    }   
    sort(line+1,line+1+cnt,cmpl);       
    for(i=1;i<=cnt;++i) 
    {
        if(line[i].pri==2) 
        {
            ans+=BIT::query(line[i].y)-BIT::query(line[i].z-1);   
        }
        else 
        {
            if(line[i].pri==1)  BIT::update(line[i].y,1);  
            else BIT::update(line[i].y,-1);    
        }
    }
    printf("%d\n",ans);   
    return 0; 
}

  

posted @ 2019-12-18 09:17  EM-LGH  阅读(147)  评论(0编辑  收藏  举报