第一次做扫描线,然后使我对线段树的理解发生了动摇= =。。这个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