poj1177Picture(线段树-周长并)

链接

神奇的扫描线啊

估计之前刷面积并的时候太急了 没来得及理解 。。

有一大段代码是与面积并一模一样的 都是离散化 更新

面积并是扫描的x  这次也一样

因为周长只算外围的 所以扫描到一条x边时 要减去上一次扫描到的 对于Y方向上 就是与面积并不大一样的地方了

看篇带图的讲解吧 网上的题解都大同小异 估计出自一人之手

http://blog.sina.com.cn/s/blog_691ce2b7010177dz.html

它是扫描的Y  其实方法是一样的 横过来就是

对于我的代码 自己感觉不好理解在于求区间数

 

  1 #include <iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<stdlib.h>

  6 using namespace std;

  7 #define N 10010

  8 #define LL long long

  9 struct node

 10 {

 11     int lx,rx,y,d;

 12     node(){}

 13     node(int a,int b,int c,int d):lx(a),rx(b),y(c),d(d){}

 14     bool operator < (const node &S) const

 15     {

 16         if(y == S.y) return d > S.d;

 17         return y<S.y;

 18     }

 19 }mat[N];

 20 int que[N],sum[N<<2],lg[N<<2],rg[N<<2],seg[N<<2];

 21 int cnt[N<<2];

 22 LL ans=0;

 23 int bin(int k,int low,int high)

 24 {

 25     int m;

 26     while(low<=high)

 27     {

 28         m  = (low+high)/2;

 29         if(que[m]==k)

 30         return m;

 31         if(que[m]>k)

 32         high = m-1;

 33         else

 34         low = m+1;

 35     }

 36     return m;

 37 }

 38 void up(int l,int r,int w)

 39 {

 40     if(cnt[w])//入边就更新这段的值 及区间数 (1个区间 2条Y边)

 41     {

 42         sum[w] = que[r+1]-que[l];

 43         seg[w] = 2;

 44         lg[w] = 1;

 45         rg[w] = 1;

 46     }

 47     else if(l==r)

 48     {

 49         sum[w] = seg[w] = lg[w] = rg[w] = 0;//出边的话 消除这条边

 50     }

 51     else//非出入边 向上更新 与平常线段树一样 等于子孩子相加

 52     {

 53         sum[w] = sum[w<<1]+sum[w<<1|1];

 54         seg[w] = seg[w<<1]+seg[w<<1|1];

 55         lg[w] = lg[w<<1];

 56         rg[w] = rg[w<<1|1];

 57         if(lg[w<<1|1]&&rg[w<<1])//左右相连 减去重复的

 58         seg[w]-=2;

 59     }

 60 }

 61 void update(int a,int b,int d,int l,int r,int w)

 62 {

 63     if(a<=l&&b>=r)

 64     {

 65         cnt[w]+=d;

 66         up(l,r,w);

 67         return ;

 68     }

 69     int m = (l+r)>>1;

 70     if(a<=m)

 71     update(a,b,d,l,m,w<<1);

 72     if(b>m)

 73     update(a,b,d,m+1,r,w<<1|1);

 74     up(l,r,w);

 75 }

 76 int main()

 77 {

 78     int i,n,a,b,c,d;

 79     while(scanf("%d",&n)!=EOF)

 80     {

 81         int num=0;

 82         for(i = 1; i <= n ; i++)

 83         {

 84             scanf("%d%d%d%d",&a,&b,&c,&d);

 85             que[num] = a;

 86             mat[num++] = node(a,c,b,1);

 87             que[num] = c;

 88             mat[num++] = node(a,c,d,-1);

 89         }

 90         sort(que,que+num);

 91         sort(mat,mat+num);

 92         int k = 1;

 93         for(i = 1 ; i < num ; i++)

 94         {

 95             if(que[i]!=que[i-1])

 96             que[k++] = que[i];

 97         }

 98         memset(cnt,0,sizeof(cnt));

 99         memset(sum,0,sizeof(sum));

100         memset(lg,0,sizeof(lg));

101         memset(rg,0,sizeof(rg));

102         memset(seg,0,sizeof(seg));

103         int o=0;

104         ans=0;

105         mat[num].y = 0;

106         for(i = 0 ; i < num ; i++)

107         {

108             int l = bin(mat[i].lx,0,k-1);

109             int r = bin(mat[i].rx,0,k-1)-1;

110             update(l,r,mat[i].d,0,k-1,1);

111             ans+=seg[1]*(mat[i+1].y-mat[i].y);

112             ans+=abs(sum[1]-o);

113             o = sum[1];

114         }

115         printf("%lld\n",ans);

116     }

117     return 0;

118 }
View Code

 

你可能感兴趣的:(poj)