//9379850 NKHelloWorld 1177 Accepted 1716K 16MS G++ 1663B 2011-10-01 14:48:33 //9379852 NKHelloWorld 1177 Accepted 1492K 32MS C++ 1663B 2011-10-01 14:48:42 /* POJ 1177 求矩形并的周长和 分横边和竖边分别计算,求和,用到了线段树 */ #include <cstdio> #include <algorithm> using namespace std; const int MAXN=5000+10,MAXR=20000+5; struct line { int p1,p2,q; bool f; void set(int a,int b,int c,bool d) { p1=a; p2=b; q=c; f=d; } } linex[MAXN<<1],liney[MAXN<<1]; struct node { int s,e,cover,m; }d[MAXR*4]; void build(int n,int ss,int ee) { d[n].s=ss; d[n].e=ee; d[n].cover=d[n].m=0; if (ss+1<ee) { int mid=(ss+ee)>>1; build((n<<1)+1,ss,mid); build((n<<1)+2,mid,ee); } } inline void refreshm(int n) { if(d[n].cover>0) d[n].m=d[n].e-d[n].s; else if (d[n].s+1<d[n].e) d[n].m=d[(n<<1)+1].m+d[(n<<1)+2].m; else d[n].m=0; } void insert(int n,int ss,int ee,int f) { if ( ss<=d[n].s && d[n].e<=ee ) { d[n].cover+=f; refreshm(n); } else { int mid=(d[n].s+d[n].e)>>1; if (ss<mid) insert((n<<1)+1,ss,ee,f); if (ee>mid) insert((n<<1)+2,ss,ee,f); refreshm(n); } } bool cmp(line a,line b) { if(a.q == b.q) return a.f > b.f; return a.q < b.q; } int calc(line * l,int n) { sort(l,l+n,cmp); build(0,0,20000); int old=0,cnt=0; for(int i=0;i<n;i++) { if(l[i].f) insert(0,l[i].p1,l[i].p2,1); else insert(0,l[i].p1,l[i].p2,-1); cnt+=abs(old-d[0].m); old=d[0].m; } return cnt; } int main() { int n; scanf("%d",&n); int x1,y1,x2,y2; for(int i=0;i<n;i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); x1+=10000;x2+=10000;y1+=10000;y2+=10000; linex[i*2].set(x1,x2,y1,true); linex[i*2+1].set(x1,x2,y2,false); liney[i*2].set(y1,y2,x1,true); liney[i*2+1].set(y1,y2,x2,false); } printf("%d\n",calc(linex,(n<<1))+calc(liney,(n<<1))); return 0; }