1 条题解

  • 0
    @ 2025-7-1 18:35:22

    一个平面有一些点,stan先竖着画一条线(必须经过一个点),ollie横着画一条线(必须经过stan画的线上的一个点),stan得分是一三象限的点数,ollie得分是二四象限的点数,在线上的不算。ollie要在自己得分最高的情况下让stan得分最少,输出stan得最低分最高的情况下的最低分,和stan得到这个分数时ollie的所有可能得分。

    参考了cxlove大神的,用两个树状数组表示竖线的左边和右边,对y离散化。一开始把所有点都加到右边的树状数组,竖线从左到右扫过去,每次把在竖线上的点从右边删除,算出在这条竖线上每个点画横线的情况a和b,更新答案:如果b比当前的ollie更大,把a和b都赋值成当前值,如果b等于当前ollie值,就把stan更新到min(stan,a)。这条线所有点更新完后的stan如果小于当前答案就把存ollie的vector清空,如果等于当前答案的话就把ollie存到vector里。

    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #include<stack>
    #include<algorithm>
    #define INF 0x3f3f3f3f
    #define eps 1e-9
    #define MAXN 200010
    #define MAXM 2000010
    #define MAXNODE MAXN*4
    #define MOD 999983
    typedef long long LL;
    using namespace std;
    int N,l[MAXN],r[MAXN],y[MAXN];
    vector<int> Ollie;
    struct Point{
        int x,y;
        bool operator < (const Point& a) const{
            return x<a.x;
        }
    }p[MAXN];
    int lowbit(int x){
        return x&(-x);
    }
    void update(int *c,int i,int v){
        while(i<=N){
            c[i]+=v;
            i+=lowbit(i);
        }
    }
    int sum(int *c,int i){
        int ret=0;
        while(i>0){
            ret+=c[i];
            i-=lowbit(i);
        }
        return ret;
    }
    int main(){
        freopen("in.txt","r",stdin);
        while(scanf("%d",&N)!=EOF&&N){
            for(int i=0;i<N;i++){
                scanf("%d%d",&p[i].x,&p[i].y);
                y[i]=p[i].y;
            }
            sort(y,y+N);
            sort(p,p+N);
            int n=unique(y,y+N)-y;
            memset(l,0,sizeof(l));
            memset(r,0,sizeof(r));
            for(int i=0;i<N;i++) update(r,lower_bound(y,y+n,p[i].y)-y+1,1);
            int Stan=-1,e;
            Ollie.clear();
            for(int i=0;i<N;i++) if(!i||p[i].x!=p[i-1].x){
                update(r,lower_bound(y,y+n,p[i].y)-y+1,-1);
                e=i;
                for(int j=i+1;j<N&&p[j].x==p[j-1].x;j++){
                    update(r,lower_bound(y,y+n,p[j].y)-y+1,-1);
                    e=j;
                }
                int stan=INF,ollie=-1;
                for(int j=i;j<=e;j++){
                    int pos=lower_bound(y,y+n,p[j].y)-y+1;
                    int a=sum(l,pos-1)+sum(r,n)-sum(r,pos),b=sum(r,pos-1)+sum(l,n)-sum(l,pos);
                    if(b==ollie) stan=min(stan,a);
                    else if(b>ollie){
                        stan=a;
                        ollie=b;
                    }
                }
                if(stan>Stan){
                    Stan=stan;
                    Ollie.clear();
                }
                if(stan==Stan) Ollie.push_back(ollie);
                for(int j=i;j<=e;j++) update(l,lower_bound(y,y+n,p[j].y)-y+1,1);
            }
            printf("Stan: %d; Ollie:",Stan);
            sort(Ollie.begin(),Ollie.end());
            n=unique(Ollie.begin(),Ollie.end())-Ollie.begin();
            for(int i=0;i<n;i++) printf(" %d",Ollie[i]);
            puts(";");
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1465
    时间
    5000ms
    内存
    64MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者