zoukankan      html  css  js  c++  java
  • poj2464扫描线好题,树状数组解法

    用树状数组解比线段树快了好多,难度也下降许多

    分别用两个树状数组维护当前扫描线左侧和右侧的点,离散化y轴即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define maxn 200005
    struct node{
        int x,y;
        bool operator<(const node p)const {
            return x<p.x;
        }
    }p[maxn];
    int y[maxn],cnt,n;
    int l[maxn],r[maxn];//两个树状数组维护扫描线左边的点数,右边的点数
    void add(int *bit,int x,int num){
        for(int i=x;i<=cnt+5;i+=i&-i)
            bit[i]+=num;
    }
    int sum(int *bit,int x){
        int res=0;
        for(int i=x;i;i-=i&-i)
            res+=bit[i];
        return res;
    }
    
    int main(){
        while(scanf("%d",&n),n){
            memset(l,0,sizeof l);
            memset(r,0,sizeof r);
            for(int i=0;i<n;i++){
                scanf("%d%d",&p[i].x,&p[i].y);
                y[i]=p[i].y;
            }
            sort(p,p+n);sort(y,y+n);
            cnt=unique(y,y+n)-y;//离散化y轴 
            for(int i=0;i<n;i++)
                add(r,lower_bound(y,y+cnt,p[i].y)-y+1,1);
            int Stan=-1,st=0;
            vector<int>Ollie;
            for(int i=1;i<=n;i++){
                if(i==n || p[i].x!=p[i-1].x){//一条竖线上的点统一处理 
                    for(int j=st;j<i;j++)
                        add(r,lower_bound(y,y+cnt,p[j].y)-y+1,-1);//把这条线上的点从r数组删去 
                    int stan=-1,ollie=-1;
                    for(int j=st;j<i;j++){
                        int pos=lower_bound(y,y+cnt,p[j].y)-y+1;
                        int a=sum(r,cnt)-sum(r,pos)+sum(l,pos-1);
                        int b=sum(l,cnt)-sum(l,pos)+sum(r,pos-1);
                        if(b==ollie) stan=min(stan,a);//使stan得分最小化 
                        else if(b>ollie) stan=a,ollie=b;//使Ollie得分最大化 
                    }
                    if(stan>Stan){Stan=stan;Ollie.clear();}//stan得分更新后同时跟新Ollie得分 
                    if(stan==Stan)Ollie.push_back(ollie);
                    for(int j=st;j<i;j++)//最后把这条线上的点加入l数组 
                        add(l,lower_bound(y,y+cnt,p[j].y)-y+1,1);
                    st=i;
                }
            }
            printf("Stan: %d; Ollie:",Stan);
            sort(Ollie.begin(), Ollie.end());
            cnt=unique(Ollie.begin(), Ollie.end())-Ollie.begin();
            for(int i=0;i<cnt;i++) printf(" %d",Ollie[i]);
            puts(";");
        }
        return 0;
    }
  • 相关阅读:
    Solr7.x学习(4)-导入数据
    Solr7.x学习(3)-创建core并使用分词器
    Solr7.x学习(2)-设置开机启动
    Solr7.x学习(1)-安装
    Java一个对象占用多少字节
    JConsole远程配置
    Docker方式安装SonarQube
    搭建Docker私有仓库
    委托
    MVC和WebApi中设置Area中的页为首页
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10115082.html
Copyright © 2011-2022 走看看