zoukankan      html  css  js  c++  java
  • 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
    ",ans);   
        return 0; 
    }
    

      

  • 相关阅读:
    字符串的输入输出 附带一道练习题
    NOIP2009 1.多项式输出
    算法--欧几里得
    小程序:2048
    虚函数和多态
    c++学习记录(十五)
    面向对象程序设计寒假作业3
    c++学习记录(十四)
    c++学习记录(十三)
    c++学习记录(十二)
  • 原文地址:https://www.cnblogs.com/guangheli/p/12058095.html
Copyright © 2011-2022 走看看