SSLOJ 1351.矩形反色

题目

题目描述

gmh77有一个无限大的方格图,由无限个1*1的格子构成,每个格子有黑白两色。初始所有格子都是白色。
现在gmh77会进行n次操作,每次把一个矩形区域反色(即黑变白,白变黑),求n次操作后得出的图形的周长(即边界长)。
边界的定义:定义一条长度为1的线段在边界上,当且仅当这条线段两侧的格子颜色不同。
注:输入中给出的是格子的坐标(不是点的坐标)

【样例解释】
每一步操作后的图形如下(为了方便用灰色代表黑色):


输入

第一行输入一个正整数n,表示操作数。
接下来n行,每行四个正整数x1,y1,x2,y2(x1<=x2,y1<=y2),分别表示操作矩形的左上角和右下角格子的坐标。

输出

一行一个数,表示图形的周长。

输入样例复制

4
1 1 3 5
2 2 4 3
2 4 5 6
3 4 4 5

输出样例复制

40

说明

【数据范围】
100%:N<=50000,1<=xi,yi<=50000
具体数据点(1个5分):
1~2:N<=10,1<=xi,yi<=10
3~4:N<=50,1<=xi,yi<=50
5~6:N<=100,1<=xi,yi<=100
7~10:N<=5000,1<=xi,yi<=5000
11~12:N<=50000,1<=xi,yi<=50000且所有两两矩形间没有公共边
13~16:N<=50,1<=xi,yi<=50000
17~20:N<=50000,1<=xi,yi<=50000

 

分析

  • 开一个差分数组,将行和列分别拆开

  • 放进离散数组,求出前缀和,如果是奇数次覆盖的话就加入答案中

代码

 1 #include<iostream>
 2 #include<cstdio> 
 3 #include<cstdlib>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=2*500001;
 7 int num;
 8 struct sb
 9 {
10     int x,l,r;
11 }a[N],e[N];
12 int b[N],v[N],s[N],cnt,ans;
13 void addl(int x,int l,int r)
14 { a[num]=(sb){x,l,r}; }
15 void adde(int x,int l,int r)
16 { e[num]=(sb){x,l,r}; }
17 bool cmp(sb a,sb b)
18 { return a.x<b.x; }
19 void fun(sb *a)
20 {
21     int L=1,R=0;
22     for (int R=1;R<=num;)
23     {
24         while (a[R].x==a[R+1].x) R++;
25         cnt=0;
26         for (int i=L;i<=R;i++)
27         {
28             b[++cnt]=a[i].l;
29             b[++cnt]=a[i].r;
30         }
31         sort(b+1,b+1+cnt);
32         cnt=unique(b+1,b+1+cnt)-b-1;
33         for (int i=1;i<=cnt;i++)
34             v[b[i]]=i,s[i]=0;
35         for (int i=L;i<=R;i++)
36             s[v[a[i].l]]++,s[v[a[i].r]]--;
37         for (int i=1;i<cnt;i++) s[i]+=s[i-1];
38         for (int i=1;i<cnt;i++) ans+=(s[i]&1)*(b[i+1]-b[i]);
39         R++; L=R; 
40     }
41 }
42 int main ()
43 {
44     int n;
45     cin>>n;
46     for (int i=1,x1,x2,y1,y2;i<=n;i++)
47     {
48         cin>>x1>>y1>>x2>>y2; x2++; y2++;
49         num++; addl(x1,y1,y2); adde(y2,x1,x2);
50         num++; adde(y1,x1,x2); addl(x2,y1,y2); 
51     }
52     sort(a+1,a+1+num,cmp);
53     sort(e+1,e+1+num,cmp);
54     fun(a); fun(e);
55     cout<<ans;
56 }

猜你喜欢

转载自www.cnblogs.com/zjzjzj/p/11312021.html