很经典的题,我是学习的罗老的代码。就是给出一些矩形,求所有矩形重叠后最终图形的边长。思路就是(内部资料,不得外传)。这题的一个坑就是矩形的边重合时的情况。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 #define N 5005
 5 #define M 20005
 6 int ans;
 7 struct Seg
 8 {
 9     int x,y1,y2;
10     bool f;
11     Seg(){}
12     Seg(int a,int b,int c,bool d)
13     {
14         x = a; y1 = b;
15         y2 = c; f = d;
16     }
17     bool operator<(const Seg &s)const
18     {
19         if(x == s.x) return f > s.f;
20         else return x < s.x;
21     }
22 };
23 Seg segx[N<<1],segy[N<<1];
24 int tree[M<<2];
25 void inst(int u,int x,int y,int s,int t,int val)
26 {
27     int mid=(x+y)>>1,lc=u<<1,rc=lc|1;
28     if(s <= x && y <= t && tree[u] != -1)
29     {
30         tree[u] += val;
31         if((val == 1 && tree[u] == 1))
32         // (val == -1 && tree[u] == 0) ||
33             ans += y-x+1;
34         return ;
35     }
36     if(tree[u] != -1)
37         tree[lc] = tree[rc] = tree[u];
38     tree[u] = -1;
39     if(s <= mid) inst(lc,x,mid,s,t,val);
40     if(t >= mid+1) inst(rc,mid+1,y,s,t,val);
41     if(tree[lc] == tree[rc]) tree[u] = tree[lc];
42 }
43 int main()
44 {
45     int n,i,x1,x2,y1,y2;
46     scanf("%d",&n);
47     for(i = 0; i < n; i++)
48     {
49         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
50         x1 += 10001;
51         x2 += 10001;
52         y1 += 10001;
53         y2 += 10001;
54         segx[2*i] = Seg(y2,x1,x2,0);
55         segx[2*i+1] = Seg(y1,x1,x2,1);
56         segy[2*i] = Seg(x2,y1,y2,0);
57         segy[2*i+1] = Seg(x1,y1,y2,1);
58     }
59     sort(segx,segx+2*n);
60     sort(segy,segy+2*n);
61     for(i = 0; i < 2*n; i++)
62     {
63         if(segx[i].f) inst(1,1,M,segx[i].y1+1,segx[i].y2,1);
64         else inst(1,1,M,segx[i].y1+1,segx[i].y2,-1);
65     }
66     for(i = 0; i < 2*n; i++)
67     {
68         if(segy[i].f) inst(1,1,M,segy[i].y1+1,segy[i].y2,1);
69         else inst(1,1,M,segy[i].y1+1,segy[i].y2,-1);
70     }
71     printf("%d\n",ans*2);
72     return 0;
73 }