zoukankan      html  css  js  c++  java
  • Codeforces 610D Vika and Segments

    题目大意:给你n(n<=1e9)条垂直于x轴或者与x轴平行的线,问你这些线占了多少个点。

    写的时候感觉就是一道线段树,可是想不出来,后来题解说可以转化成面积问题,就知道

    怎么写了,是一道线段树加扫描线求面积并的问题。

    思路:将一条线转化为宽度为1的矩形,然后用线段树+扫描线+离散化求面积并就行了,

    顺便帮我复习了一下扫描线。。 以后要多想想怎么转化不能这么菜了!!!!

    #include<bits/stdc++.h>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define ll long long
    using namespace std;
    const int N=2*1e5+3;
    struct line
    {
        int x,y1,y2,op;
        bool operator < (const line &t)const
        {
            if(x==t.x) return op<t.op;
            return x<t.x;
        }
    }e[N];
    int n,y[N],tot=0,cnt=0;
    int seg[N<<2],cover[N<<2]; //seg[i] 表示i这个区域内的覆盖长度,cover表示覆盖了几次。
    void push_up(int rt,int l,int r,int op)
    {
        if(cover[rt]>=1) seg[rt]=y[r+1]-y[l];
        else if(l==r)
        {
            if(op==1) seg[rt]=y[r+1]-y[l];
            else seg[rt]=0;
        }
        else seg[rt]=seg[rt<<1]+seg[rt<<1|1];
    }
    void updata(int L,int R,int l,int r,int rt,int g)
    {
        if(l>=L && r<=R)
        {
            cover[rt]+=g;
            push_up(rt,l,r,g);
            return;
        }
        int m=(l+r)>>1;
        if(L<=m) updata(L,R,lson,g);
        if(R>m) updata(L,R,rson,g);
        push_up(rt,l,r,g);
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            if(y1>y2) swap(y1,y2),swap(x1,x2);
            if(y1==y2)
            {
                e[tot].x=x1; e[tot].y1=y1; e[tot++].y2=y1+1;
                e[tot].x=x2; e[tot].y1=y1; e[tot++].y2=y1+1;
                y[cnt++]=y1; y[cnt++]=y1+1;
                if(x1>x2) e[tot-2].x+=1,e[tot-1].op=1,e[tot-2].op=-1;
                else e[tot-1].x+=1,e[tot-2].op=1,e[tot-1].op=-1;
            }
            else
            {
                e[tot].x=x1; e[tot].op=1; e[tot].y1=y1; e[tot++].y2=y2+1;
                e[tot].x=x1+1; e[tot].op=-1; e[tot].y1=y1; e[tot++].y2=y2+1;
                y[cnt++]=y1; y[cnt++]=y2+1;
                if(x1>x2) e[tot-1].op=1,e[tot-2].op=-1;
                else e[tot-1].op=-1,e[tot-2].op=1;
            }
        }
        sort(y,y+cnt); sort(e,e+tot);
        cnt=unique(y,y+cnt)-y;
        ll ans=0,pre=-1e18;
        for(int i=0;i<tot;i++)
        {
            if(pre!=-1e18) ans+=(ll)(e[i].x-pre)*(ll)seg[1];
            int up=lower_bound(y,y+cnt,e[i].y2)-y;
            int down=lower_bound(y,y+cnt,e[i].y1)-y;
            updata(down,up-1,0,tot-1,1,e[i].op);
            pre=e[i].x;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    scheduletask任务调度(2间隔时间)
    scheduletask任务调度
    初始webservice
    ssh整合
    aop
    自定义框架(MyMvc)
    数据校验
    原生态ajax
    struts2国际化
    文件下载
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7400409.html
Copyright © 2011-2022 走看看