求给出矩形的周长。
这是一道周长扫描线题,比较裸。juruo第一次打打了一个多小时。
代码:
#include<cmath> #include<cstdio> #include<algorithm> using namespace std; #define N 5005 int n,tot; struct EDge { int l,r,s,v; EDge(){} EDge(int l,int r,int s,int v):l(l),r(r),s(s),v(v){} friend bool operator < (EDge a,EDge b) { if(a.s!=b.s)return a.s<b.s; return a.v>b.v; } }ex[2*N]; struct Segtree { int sum; int num; int len; bool lfg,rfg; }tr[80005]; void update(int u,int l,int r) { if(tr[u].sum) { tr[u].num=1; tr[u].len=r-l+1; tr[u].lfg=tr[u].rfg=1; }else if(l==r) { tr[u].num=0; tr[u].len=0; tr[u].lfg=tr[u].rfg=0; }else { tr[u].num=tr[u<<1].num+tr[u<<1|1].num; tr[u].len=tr[u<<1].len+tr[u<<1|1].len; if(tr[u<<1].rfg&&tr[u<<1|1].lfg)tr[u].num--; tr[u].lfg=tr[u<<1].lfg; tr[u].rfg=tr[u<<1|1].rfg; } } void Insert(int l,int r,int u,int ql,int qr,int v) { if(l==ql&&r==qr) { tr[u].sum+=v; update(u,l,r); return ; } int mid = (l+r)>>1; if(qr<=mid)Insert(l,mid,u<<1,ql,qr,v); else if(ql>mid)Insert(mid+1,r,u<<1|1,ql,qr,v); else Insert(l,mid,u<<1,ql,mid,v),Insert(mid+1,r,u<<1|1,mid+1,qr,v); update(u,l,r); } int main() { scanf("%d",&n); int x_1,y_1,x_2,y_2,mn=0x7fffffff,mx=-0x7fffffff; for(int i=1;i<=n;i++) { scanf("%d%d%d%d",&x_1,&y_1,&x_2,&y_2); ex[++tot]=EDge(x_1,x_2,y_1,1); ex[++tot]=EDge(x_1,x_2,y_2,-1); mx=max(mx,max(x_1,x_2)); mn=min(mn,min(x_1,x_2)); } if(mn<=0) { for(int i=1;i<=tot;i++)ex[i].l-=mn-1,ex[i].r-=mn-1; mx-=mn-1; } sort(ex+1,ex+tot+1); int ans = 0,las = 0; for(int i=1;i<=tot;i++) { Insert(1,mx,1,ex[i].l,ex[i].r-1,ex[i].v); while(ex[i+1].s==ex[i].s&&ex[i+1].v==ex[i].v) { i++; Insert(1,mx,1,ex[i].l,ex[i].r-1,ex[i].v); } ans+=abs(tr[1].len-las); las =tr[1].len; ans+=tr[1].num*2*(ex[i+1].s-ex[i].s); } printf("%d ",ans); return 0; }