luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树
Posted guangheli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树相关的知识,希望对你有一定的参考价值。
Code:
#include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void setIO(string s) string in=s+".in"; freopen(in.c_str(),"r",stdin); struct Edge int l,r,h,flag; edges[maxn]; int n; namespace tr #define ls lson[o] #define rs rson[o] #define mid ((l+r)>>1) int tot; int lson[maxn<<2],rson[maxn<<2],lflag[maxn<<2],rflag[maxn<<2],sumv[maxn<<2],numv[maxn<<2],len[maxn<<2]; int newnode() return ++tot; void pushup(int o,int l,int r) if(sumv[o]) numv[o]=1; len[o]=r-l+1; lflag[o]=rflag[o]=1; else len[o]=len[ls]+len[rs]; numv[o]=numv[ls]+numv[rs]; if(rflag[ls]&&lflag[rs]) --numv[o]; lflag[o]=lflag[ls]; rflag[o]=rflag[rs]; void add(int &o,int l,int r,int L,int R,int v) if(!o) o=newnode(); if(l>=L&&r<=R) sumv[o]+=v; pushup(o,l,r); return; if(L<=mid) add(ls,l,mid,L,R,v); if(R>mid) add(rs,mid+1,r,L,R,v); pushup(o,l,r); ; bool cmp(Edge a,Edge b) if(a.h==b.h) return a.flag > b.flag; else return a.h < b.h; int main() // setIO("input"); scanf("%d",&n); int a,b,c,d,i,ed=0,j,root=0,last=0,ans=0; for(i=1;i<=n;++i) scanf("%d%d%d%d",&a,&b,&c,&d); edges[++ed].l=a,edges[ed].r=c-1,edges[ed].h=b,edges[ed].flag=1; // 加边 edges[++ed].l=a,edges[ed].r=c-1,edges[ed].h=d,edges[ed].flag=-1; // 删边 sort(edges+1,edges+1+ed,cmp); for(i=1;i<=ed;++i) tr::add(root,-inf,inf,edges[i].l,edges[i].r,edges[i].flag); ans+=abs(tr::len[root]-last); last=tr::len[root]; ans+=((tr::numv[root]<<1)*(edges[i+1].h-edges[i].h)); printf("%d\n",ans); return 0;
以上是关于luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树的主要内容,如果未能解决你的问题,请参考以下文章
USACO5.5 矩形周长 Picture | 扫描线 + 线段树