zoukankan      html  css  js  c++  java
  • Fence the vegetables fail

    题意:给你一些坐标,代表篱笆的顶点和或者蔬菜,问你篱笆外面的蔬菜价值几何?

    思路:扫描线+线段树或树装数组

    鉴于这道题找了四五个小时的bug,还是写出来庆祝一下终于到来的AC;

    因为这里坐标太大了,按照惯例离散一下,那我就从下面往上面扫,因为不是多个图形的叠加,没有必要标注上下边,而且很难分辨上下边(当然我开始写的时候是很傻逼想标来着,后来想到计算奇数偶数即可啊),这样的话,就用线段树维护一下区间即可,复杂度nlogn,排出bug,一身轻松~~~

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    const LL INF=0x3f3f3f3f;
    const int maxn=1e5+20;
    int n,m,cntx,cntp,c[maxn<<1];
    LL x[maxn<<1];
    struct point
    {
        LL l,r,h;int k,v;
        point(LL _l=0,LL _r=0,LL _h=0,int _k=0,int _v=0):l(_l),r(_r),h(_h),k(_k),v(_v){}
        bool operator <(const point &r)const{return h<r.h;}
    }p[maxn<<1];
    
    void add(LL *xx,LL *yy)
    {
        if(yy[0]==yy[1])
          p[cntp++]=point(min(xx[0],xx[1]),max(xx[0],xx[1]),yy[0],1,0);
    }
    int Lowbit(int x){return x&(-x);}
    
    void update(int i,int x)
    {
        while(i>0)
         {
             c[i]+=x;
             i-=Lowbit(i);
         }
    }
    
    int sum(int x,int tol)
    {
        int sum=0;
        while(x<=tol)
         {
             sum+=c[x];
             x+=Lowbit(x);
         }
        return sum;
    }
    
    int main()
    {
        //freopen("F_37.in","r",stdin);
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            cntp=0,cntx=1;
            LL xx[2],yy[2],tx,ty;
            for(int i=0;i<n;i++)
            {
                scanf("%I64d%I64d",&xx[0],&yy[0]);
                p[cntp++]=point(xx[0],yy[0],yy[0],0,i+1);
                x[cntx++]=xx[0];
            }
            scanf("%I64d%I64d",&xx[0],&yy[0]);
            tx=xx[0],ty=yy[0];x[cntx++]=xx[0];
            for(int i=1;i<m;i++)
            {
              scanf("%I64d%I64d",&xx[1],&yy[1]);
              x[cntx++]=xx[1];add(xx,yy);
              xx[0]=xx[1],yy[0]=yy[1];
            }
            xx[1]=tx,yy[1]=ty; add(xx,yy);x[0]=-1e10;
            sort(x,x+cntx);
            sort(p,p+cntp);
            int tol=2;
            for(int i=2;i<cntx;i++)
                if(x[i]!=x[i-1])
                    x[tol++]=x[i];
            memset(c,0,(m+n+10)*sizeof(int));
            LL ans=0;
            for(int i=0;i<cntp;i++)
            {
                if(p[i].k)
                {
                    int tl=lower_bound(x,x+tol,p[i].l)-x;
                    int tr=lower_bound(x,x+tol,p[i].r)-x;
                    update(tr-1,1);update(tl-1,-1);
                }
                else
                {
                    int tx=lower_bound(x,x+tol,p[i].l)-x;
                    if(!(sum(tx,tol)&1))ans+=1LL*p[i].v;
                }
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    (转)Golang reflect.DeepEqual函数:判断两个值是否一致
    Kubernetes字段Finalizers
    校园电子屏无人值守模式探索
    史上最全测试开发工具推荐(含自动化、性能、稳定性、抓包)
    Java 将Word转为HTML的方法
    C# 在PPT中添加数学公式
    C# 将PPT转为OFD/DPT/DPS/ODP/POTX/UOP
    C# 将Excel转为OFD、UOS
    Java 扫描识别条形码图片
    C# 加载Word的3种方法
  • 原文地址:https://www.cnblogs.com/MeowMeowMeow/p/7327683.html
Copyright © 2011-2022 走看看