1 条题解

  • 0
    @ 2026-4-18 23:38:29

    蒟蒻今天才刚补完这道题,想顺便写一发题解

    做法: 扫描线+线段树维护

    这道题,干想挺难想,所以我们可以换个思路去理解这道题,而不是死板的想怎么包围

    可以将每条竖直的线进行维护,用扫描线的做法。

    接着存下每条竖直的线,sort排序相应的x值

    最后用线段树维护,这条边是右边的边还是左边的边,如果是右边的边那接下来的线层数相当于这条线左边的层数-1,否则就为这条边左边的层数+1

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    const int M=200000+5;
    struct node{
    	int x,y1,y2,flag;
    	bool operator < (const node &_) const{
    		return x<_.x;
    	}
    }A[M];
    
    int B[M],C[M];
    /************Segment_Tree************/
    struct Seg_Tree{
    	int l,r,sum,lazy;
    	#define l(x) tree[x].l
    	#define r(x) tree[x].r
    	#define sum(x) tree[x].sum
    	#define lazy(x) tree[x].lazy
    }tree[M<<2];
    
    void Down(int p){
    	if(!lazy(p)) return;
    	sum(p<<1)+=lazy(p); lazy(p<<1)+=lazy(p);
    	sum(p<<1|1)+=lazy(p); lazy(p<<1|1)+=lazy(p);
    	lazy(p)=0;
    	return;
    }
    
    void Up(int p){
    	sum(p)=min(sum(p<<1),sum(p<<1|1));
    }
    
    void build(int p, int l, int r){
    	l(p)=l, r(p)=r, sum(p)=lazy(p)=0;
    	if(l==r) return;
    	int mid=l+r>>1;
    	build(p<<1,l,mid); build(p<<1|1,mid+1,r);
    	return;
    }
    
    void Upd(int p, int l, int r, int x){
    	if(l(p)==l && r(p)==r){
    		sum(p)+=x; lazy(p)+=x;
    		return;
    	}
    	Down(p);
    	int mid=l(p)+r(p)>>1;
    	if(r<=mid) Upd(p<<1,l,r,x);
    	else if(l>mid) Upd(p<<1|1,l,r,x);
    	else Upd(p<<1,l,mid,x), Upd(p<<1|1,mid+1,r,x);
    	Up(p);
    }
    
    int Que(int p, int l, int r){
    	if(l(p)==l && r(p)==r){
    		return sum(p);
    	}
    	Down(p);
    	int mid=l(p)+r(p)>>1;
    	if(r<=mid) return Que(p<<1,l,r);
    	else if(l>mid) return Que(p<<1|1,l,r);
    	else return min(Que(p<<1,l,mid),Que(p<<1|1,mid+1,r));
    }
    /************Main************/
    int main(){
    	int n,cnt=0,tot=0;
    	scanf("%d",&n);
    	for(int i=1,x; i<=n; i++){
    		scanf("%d",&x);
    		for(int j=1; j<=x; j++) scanf("%d",&C[j]);
         	//存入每条竖直的线
    		for(int j=3; j<x; j+=2) A[++tot]=(node)<%C[j],C[j-1],C[j+1],C[j-1]<C[j+1]?-1:1%>,B[++cnt]=C[j-1],B[++cnt]=C[j+1];
    		A[++tot]=(node)<%C[1],C[2],C[x],C[2]<C[x]?1:-1%>,B[++cnt]=C[2],B[++cnt]=C[x];
    	}
    	sort(B+1,B+cnt+1); cnt=unique(B+1,B+cnt+1)-B-1;
    	sort(A+1,A+tot+1); build(1,1,tot);
    	int ans=0;
    	for(int i=1; i<=tot; i++){
    		int a=lower_bound(B+1,B+cnt+1,A[i].y1)-B,b=lower_bound(B+1,B+cnt+1,A[i].y2)-B;//对每条线的y值进行离散化,方便放入树中
    		int l=min(a,b),r=max(a,b);
    		Upd(1,l,r,A[i].flag);
    		ans=max(ans,Que(1,l,r));
    	}
    	printf("%d\n",ans);
    	return 0;
    }
    

    蒟蒻也是第一次写博客,欢迎大佬们来喷

    • 1

    信息

    ID
    3743
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者