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 }
时间: 2024-10-16 00:57:23

HDU 3265 Posters ——(线段树+扫描线)的相关文章

HDU 3265 Posters (线段树+扫描线)(面积并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 给你n个中间被挖空了一个矩形的中空矩形,让你求他们的面积并. 其实一个中空矩形可以分成4个小的矩形,然后就是面积并,特别注意的是x1 == x3 || x2 == x4的时候,要特判一下,否则会RE. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algori

hdu 1828 Picture(线段树&amp;扫描线&amp;周长并)

Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2578    Accepted Submission(s): 1363 Problem Description A number of rectangular posters, photographs and other pictures of the same shap

HDU 1828 Picture 线段树+扫描线

题意:给你一些矩形的左上角点的坐标和右下角点的坐标,求周长并 最显而易见的思路就是对于x轴和y轴做两次扫描线,对于负数的坐标进行离散化.每次增加的值是线段变化量的绝对值.具体写法和求面积并的差不多. #include <cstdio> #include <algorithm> #include <cstring> #include <vector> using namespace std; #define lson rt << 1 , l , m

HDU 1542 Atlantis(线段树扫描线)

http://acm.hdu.edu.cn/showproblem.php?pid=1542 Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6788    Accepted Submission(s): 2970 Problem Description There are several ancient Greek

hdu 1542 Atlantis(线段树&amp;扫描线&amp;面积并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6386    Accepted Submission(s): 2814 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

hdu 1542 Atlantis (线段树+扫描线)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18559    Accepted Submission(s): 7523 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8998    Accepted Submission(s): 3856 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

hdu 3642(线段树+扫描线)

三维扫描线,枚举z寻找相交区间的立方体,然后直接扫描线求xy平面的相交三次及以上面积,乘以z区间求和就可以了 #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const int maxn=1e6+100; const int maxm=2000+500; int col[maxn<<2]; int

hdu 1542(线段树+扫描线 求矩形相交面积)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12059    Accepted Submission(s): 5083 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

【HDU】1828-Picture(线段树扫描线)

矩阵交并周长的模板题 这题不需要离散化,需要注意的时候负坐标转化成正坐标 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define lson (pos<<1) #define rson (pos<<1|1) typedef long long LL; const int maxn = 30005; const int ADD = 1000