HDU 3265 Posters ——(线段树+扫描线)

Posted Storm_Spirit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3265 Posters ——(线段树+扫描线)相关的知识,希望对你有一定的参考价值。

  第一次做扫描线,然后使我对线段树的理解发生了动摇= =。。这个pushup写的有点神奇。代码如下:

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <string.h>
  4 #define t_mid (l+r>>1)
  5 #define ls (o<<1)
  6 #define rs (o<<1|1)
  7 #define lson ls,l,t_mid
  8 #define rson rs,t_mid+1,r
  9 using namespace std;
 10 const int N = 50000 + 5;
 11 const int MAXN = 50000 + 5 ;
 12 typedef long long ll;
 13 
 14 struct seg
 15 {
 16     int x1,x2,y,d;
 17     bool operator < (const seg & temp) const
 18     {
 19         // 先加边后减边,这样的话就不会出现lazy[o] < 0的情况了
 20         return y == temp.y ? d > temp.d : y < temp.y;
 21     }
 22 }g[N*8];
 23 int n,tot,c[MAXN<<2],lazy[MAXN<<2];
 24 
 25 void add(int x1,int x2,int y,int d)
 26 {
 27     tot ++;
 28     g[tot] = {x1,x2,y,d};
 29 }
 30 void read()
 31 {
 32     tot = 0;
 33     for(int i=1;i<=n;i++)
 34     {
 35         int x1, y1, x2, y2, x3, y3, x4, y4;
 36         scanf("%d%d%d%d%d%d%d%d",&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4);
 37         if(x1 != x3)
 38         {
 39             add(x1,x3,y1,1);
 40             add(x1,x3,y2,-1);
 41         }
 42         if(x4 != x2)
 43         {
 44             add(x4,x2,y1,1);
 45             add(x4,x2,y2,-1);
 46         }
 47         add(x3,x4,y1,1);
 48         add(x3,x4,y3,-1);
 49         add(x3,x4,y4,1);
 50         add(x3,x4,y2,-1);
 51     }
 52     sort(g+1,g+1+tot);
 53 }
 54 
 55 void up(int o) {c[o] = c[ls] + c[rs];}
 56 /*void down(int o,int l,int r)
 57 {
 58     if(l == r) return ;
 59     int len = r - l + 1;
 60     if(lazy[o])
 61     {
 62         lazy[ls] = lazy[rs] = lazy[o];
 63         if(lazy[o] > 0)
 64         {
 65             c[ls] = len - len / 2;
 66             c[rs] = len / 2;
 67         }
 68         else
 69         {
 70             c[ls] = c[rs] = 0;
 71         }
 72         lazy[o] = 0;
 73     }
 74 }*/
 75 
 76 void pushup(int o,int l,int r)
 77 {
 78     if(lazy[o] > 0)
 79     {
 80         //if(lazy[o] < 0) for(int i=1;i<=1000000000000LL;i++);
 81         // 注意seg的排序规则!
 82         c[o] = r - l + 1;
 83     }
 84     else
 85     {
 86         // lazy[o] == 0
 87         if(l == r) c[o] = 0;
 88         else up(o);
 89     }
 90 }
 91 void update(int o,int l,int r,int ql,int qr,int f)
 92 {
 93     if(l == ql && r == qr)
 94     {
 95         lazy[o] += f;
 96         pushup(o,l,r);
 97         return ;
 98     }
 99     if(qr <= t_mid) update(lson,ql,qr,f);
100     else if(ql > t_mid) update(rson,ql,qr,f);
101     else
102     {
103         update(lson,ql,t_mid,f);
104         update(rson,t_mid+1,qr,f);
105     }
106     pushup(o,l,r);
107 }
108 
109 void solve()
110 {
111     ll ans = 0;
112     memset(c,0,sizeof(c));
113     memset(lazy,0,sizeof(lazy));
114     for(int i=1;i<=tot;)
115     {
116         int j = i;
117         while(j <= tot && g[j].y == g[i].y) j++;
118         for(int k=i;k<j;k++) update(1,0,MAXN,g[k].x1+1,g[k].x2,g[k].d);
119         if(j <= tot) ans += (ll)(c[1])*(g[j].y-g[i].y);
120         i = j;
121     }
122     printf("%I64d\n",ans);
123 }
124 
125 int main()
126 {
127     while(scanf("%d",&n) == 1 && n)
128     {
129         read();
130         solve();
131     }
132     return 0;
133 }

 

以上是关于HDU 3265 Posters ——(线段树+扫描线)的主要内容,如果未能解决你的问题,请参考以下文章

Mayor's posters(离散化线段树)

线段树 Mayor's posters

NSOJ 4621 posters (离散化+线段树)

线段树Mayor's posters

Mayor's posters 线段树区间覆盖

POJ 2528-Mayor's posters-线段树+离散化