zoukankan      html  css  js  c++  java
  • [扫描线][线段树]JZOJ 4238 纪念碑

    Description

    2034年,纪念中学决定修建校庆100周年纪念碑,作为杰出校友的你被找了过来,帮校方确定纪念碑的选址.
    纪念中学的土地可以看作是一个长为n,宽为m的矩形.它由n* m个1*1的正方形组成,其中左下角的正方形的坐标为(1,1),右上角的正方形的坐标为(n, m).其中有一些土地已经被用来修建建筑物,每一幢建筑物都可以看做是一个左下角为(x1,y1),右上角为(x2,y2)的矩形.
    纪念碑可以看作是一个正方形.校方希望你找出一块最大的正方形区域供他们参考.
     

    Input

    每一组数据的第一行包含三个整数n,m和p,分别表示学校的长,宽以及建筑物的数量.
    接下来的p行,每行包含四个整数x1,y1,x2,y2,分别表示每一幢建筑物左下角以及右上角的坐标.

    Output

    输出一个数,表示可能的最大边长.
     

    Sample Input

    13 5 8
    8 4 10 4
    4 3 4 4
    10 2 12 2
    8 2 8 4
    2 4 6 4
    10 3 10 4
    12 3 12 4
    2 2 4 2

    Sample Output

    3
     

    Data Constraint

    对于30%的数据,p<=1000.
    对于70%的数据,p<=30000.
    对于100%的数据,p<=400000,m,n<=1000000.

    分析

    一看什么矩阵重叠啊什么的先考虑一下扫描线

    然后我们用扫描线+线段树维护

    扫描线确定横向距离,线段树确定纵向最大空区间

    挺好搞的,线段树三个值,一个是从左往右的最大空区间,另一个从右往左,还有一个最大的

    更新一下就行,不需要下传标记,因为扫描线迟早会把它去掉

    #include <iostream>
    #include <cstdio>
    #include <vector>
    using namespace std;
    #define lson (x<<1)
    #define rson ((x<<1)+1)
    const int N=1e6+10;
    struct Seg {
        int len;
        int v[3],lz;//left right max
    }t[4*N];
    struct Interval {
        int y1,y2;
    };
    vector<Interval> add[N],del[N];
    int n,m,p;
    
    void Update(int x) {
        if (t[x].lz) {
            t[x].v[0]=t[x].v[1]=t[x].v[2]=0;return;
        }
        if (t[x].len==1) {
            t[x].v[0]=t[x].v[1]=t[x].v[2]=1;return;
        }
        t[x].v[0]=t[lson].v[0]+(t[lson].v[0]==t[lson].len)*t[rson].v[0];
        t[x].v[1]=t[rson].v[1]+(t[rson].v[1]==t[rson].len)*t[lson].v[1];
        t[x].v[2]=max(t[lson].v[1]+t[rson].v[0],max(t[lson].v[2],t[rson].v[2]));
    }
    
    void Build(int x,int l,int r) {
        t[x].len=t[x].v[0]=t[x].v[1]=t[x].v[2]=r-l+1;
        if (l==r) return;
        int mid=l+r>>1;
        Build(lson,l,mid);Build(rson,mid+1,r);
    }
    
    void Change(int x,int l,int r,int xl,int xr,int k) {
        if (xl<=l&&r<=xr) {
            t[x].lz+=k;Update(x);return;
        }
        int mid=l+r>>1;
        if (xl<=mid) Change(lson,l,mid,xl,xr,k);
        if (mid<xr) Change(rson,mid+1,r,xl,xr,k);
        Update(x);
    }
    
    int main() {
        scanf("%d%d%d",&n,&m,&p);
        for (int i=1,x1,x2,y1,y2;i<=p;i++) scanf("%d%d%d%d",&x1,&y1,&x2,&y2),add[x1].push_back((Interval){y1,y2}),del[x2].push_back((Interval){y1,y2});
        Build(1,1,m);
        int l=1,r=1,ans=0;
        while (r<=n) {
            for (int i=0;i<add[r].size();i++) Change(1,1,m,add[r][i].y1,add[r][i].y2,1);
            ans=max(ans,min(t[1].v[2],r-l+1));
            if (r-l+1>t[1].v[2]) {
                for (int i=0;i<del[l].size();i++) Change(1,1,m,del[l][i].y1,del[l][i].y2,-1);
                l++;
            }
            r++;
        }
        printf("%d
    ",ans);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    SQL Server DATALENGTH Functions
    SQL Server SUBSTRING Functions
    SQL Server LOWER Functions
    SQL Server CHARINDEX Functions
    SQL Server循环不连续的日期时间
    SQL Server 加号[+] 字符串串联运算符
    SQL Server LTRIM Functions
    SQL Server STUFF Functions
    SQL Server RIGHT Functions
    SQL Server LEN Functions
  • 原文地址:https://www.cnblogs.com/mastervan/p/10335974.html
Copyright © 2011-2022 走看看