[51nod1206]Picture

  给你一坨矩形,问这些矩形组成的所有多边形的周长之和。

  分别求竖着的边和横着的边。

  离散化后线段树,维护当前行(或者列)有多少没在多边形里的,添加矩形就变成添加、删除线段。

  每次加线段或删线段时累加一下贡献(加线段时的贡献就是加完后那条线段里有多少个位置变成在多边形里,删线段时的贡献就是删完后有多少个位置变成不在多边形里)。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #define ll long long
 9 #define ull unsigned long long
10 #define d double
11 using namespace std;
12 const int maxn=100233,mxnode=maxn*50;
13 struct zs{int h,l,r;bool add;}b[maxn];int n1;
14 struct mat{int x1,y1,x2,y2;}a[50023];
15 int lc[mxnode],rc[mxnode],mn[mxnode],num[mxnode],add[mxnode],tot,MX;
16 int i,j,k,n,m,L,R,V;
17 ll ans;
18 
19 int ra,fh;char rx;
20 inline int read(){
21     rx=getchar(),ra=0,fh=1;
22     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
23     if(rx=='-')fh=-1,rx=getchar();
24     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
25 }
26 
27 inline void ins(int &x,int l){x=++tot,mn[x]=add[x]=0,num[x]=l;}
28 inline void upd(int x){
29     int l=lc[x],r=rc[x];
30     if(mn[l]>mn[r])swap(l,r);
31     if(mn[l]==mn[r])mn[x]=mn[l]+add[x],num[x]=num[l]+num[r];
32     else mn[x]=mn[l]+add[x],num[x]=num[l];
33 }
34 void insert(int x,int a,int b){
35 //    printf("insert:%d--%d      %d-----%d\n",a,b,L,R);
36     if(L<=a&&R>=b){add[x]+=V,mn[x]+=V;return;}
37     int mid=a+b>>1;
38     if(!lc[x])ins(lc[x],mid-a+1);if(!rc[x])ins(rc[x],b-mid);
39     if(L<=mid)insert(lc[x],a,mid);
40     if(R>mid)insert(rc[x],mid+1,b);
41     upd(x);//printf("%d--%d  mn:%d   num:%d\n",a,b,mn[x],num[x]);
42 }
43 
44 inline int get0(){return mn[1]!=0?0:num[1];}
45 bool cmp(zs a,zs b){return a.h<b.h||(a.h==b.h&&a.add);}
46 inline void calc(){
47     int i;
48     sort(b+1,b+1+n1,cmp);
49     for(i=1;i<=tot;i++)lc[i]=rc[i]=0;tot=1,mn[1]=add[1]=0,num[1]=MX;
50     for(i=1;i<=n1;i++){
51         L=b[i].l,R=b[i].r;
52         if(b[i].add)ans+=get0(),V=1,insert(1,1,MX),ans-=get0();
53         else ans-=get0(),V=-1,insert(1,1,MX),ans+=get0();//printf("num0:%d    mn:%d\n",get0(),mn[1]);
54     }//printf("  ans:%d\n",ans);
55 }
56 
57 inline int abs1(int x){return x<0?-x:x;}
58 inline int max(int a,int b){return a>b?a:b;}
59 int main(){
60     n=read();int tmp;
61     for(i=1;i<=n;i++){
62         a[i].x1=read(),a[i].y1=read(),a[i].x2=read()-1,a[i].y2=read()-1;
63         tmp=max(max(abs1(a[i].x1),abs1(a[i].x2)),max(abs1(a[i].y1),abs1(a[i].y2)));
64         if(tmp>MX)MX=tmp;
65     }
66     for(i=1;i<=n;i++)a[i].x1+=MX+1,a[i].x2+=MX+1,a[i].y1+=MX+1,a[i].y2+=MX+1;
67     MX=MX<<1|1;
68     n1=0;
69     for(i=1;i<=n;i++)
70         b[++n1]=(zs){a[i].x1,a[i].y1,a[i].y2,1},
71         b[++n1]=(zs){a[i].x2+1,a[i].y1,a[i].y2,0};
72     calc();
73     n1=0;
74     for(i=1;i<=n;i++)
75         b[++n1]=(zs){a[i].y1,a[i].x1,a[i].x2,1},
76         b[++n1]=(zs){a[i].y2+1,a[i].x1,a[i].x2,0};
77     calc();
78     printf("%lld\n",ans);
79 }
View Code

 

posted @ 2016-10-09 15:41  czllgzmzl  阅读(253)  评论(0编辑  收藏  举报