标签:des style blog http os 2014
7 -15 0 5 10 -5 8 20 25 15 -4 24 14 0 -6 16 4 2 15 10 22 30 10 36 20 34 0 40 16
228
思路:求纵向边要维护重叠次数大于0的纵向长度,用上一次的node[1].m减去当前的node[1].m的绝对值。求横向边要维护每一次更新之后需要加上去的边数。
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; struct L{ int val;//1 左边,-1 右边 int x,y1,y2; }l[10000]; struct N{ int l,r,n,m;//n记录节点对应的有效横向边数量,m记录纵向长度 int cnt;//重叠情况 bool lc,rc; }node[40000]; int tempy[10000]; bool cmp(struct L a,struct L b) { if(a.x==b.x) return a.val>b.val; return a.x<b.x; } void build(int idx,int s,int e) { node[idx].cnt=0; node[idx].m=0; node[idx].lc=node[idx].rc=0; node[idx].l=tempy[s-1]; node[idx].r=tempy[e-1]; if(s+1!=e) { int mid=(s+e)>>1; build(idx<<1,s,mid); build(idx<<1|1,mid,e); } } void len(int idx,int s,int e) { if(node[idx].cnt>0) { node[idx].m=node[idx].r-node[idx].l; node[idx].n=2;//对应两条边 node[idx].lc=node[idx].rc=1; } else { if(s+1!=e) { int mid=(s+e)>>1; node[idx].m=node[idx<<1].m+node[idx<<1|1].m; node[idx].n=node[idx<<1].n+node[idx<<1|1].n; node[idx].lc=node[idx<<1].lc; node[idx].rc=node[idx<<1|1].rc; if(node[idx<<1].rc && node[idx<<1|1].lc) node[idx].n-=2;//如果左右儿子是连着的,就要减去多计算的两条边 } else { node[idx].m=0; node[idx].n=0; node[idx].lc=node[idx].rc=0; } } } void update(int idx,int s,int e,struct L line) { if(node[idx].l==line.y1 && node[idx].r==line.y2) { node[idx].cnt+=line.val; len(idx,s,e); return; } if(s+1!=e) { int mid=(s+e)>>1; if(line.y2<=node[idx<<1].r) update(idx<<1,s,mid,line); else if(line.y1>=node[idx<<1|1].l) update(idx<<1|1,mid,e,line); else { int temp=line.y2; line.y2=node[idx<<1].r; update(idx<<1,s,mid,line); line.y2=temp; line.y1=node[idx<<1|1].l; update(idx<<1|1,mid,e,line); } } len(idx,s,e); } int main() { int T,n,i,t; int x1,x2,y1,y2; while(~scanf("%d",&n)) { for(i=0;i<n;i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); tempy[i*2]=y1; tempy[i*2+1]=y2; l[i*2].val=1; l[i*2].x=x1; l[i*2].y1=y1; l[i*2].y2=y2; l[i*2+1].val=-1; l[i*2+1].x=x2; l[i*2+1].y1=y1; l[i*2+1].y2=y2; } sort(tempy,tempy+n*2); sort(l,l+n*2,cmp); t=unique(tempy,tempy+n*2)-tempy;//去重 build(1,1,t); int ans=0,last=0; for(i=0;i<n*2;i++) { if(i) ans+=node[1].n*(l[i].x-l[i-1].x); update(1,1,t,l[i]); ans+=abs(node[1].m-last); last=node[1].m; } printf("%d\n",ans); } }
HDU-1828-Picture(线段树),布布扣,bubuko.com
标签:des style blog http os 2014
原文地址:http://blog.csdn.net/faithdmc/article/details/37558639