题目:
题意:
有
n
n
n此操作,每次操作给出矩形的左上端点坐标和右下端点坐标
每次操作后对于矩形内的方块的颜色都进行取反
求边界的总长
分析:
我们试着手玩样例,发现一条边对答案存在贡献,当且仅当该边被若干个矩形覆盖了奇数次
因此我们可以用差分来记录状态
因为坐标之间相差较大,我们考虑用离散化来做到优秀的储存
代码:
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#define LL long long
#define LZX Mu
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
struct node{
int w,l,r;
}a[100005],b[100005];
int cnt=0,ans=0;
bool cmp(node x,node y) {return x.w<y.w;}
void add1(int x,int l,int r) {a[++cnt]=(node){x,l,r};return;}
void add2(int x,int l,int r) {b[cnt]=(node){x,l,r};return;}
int d[100005],num[100005],sum[100005];
void ask(node *c)
{
int l=1,r=0;
for(r=1;r<=cnt;)
{
while(c[r].w==c[r+1].w) r++;
int len=0;
for(int i=l;i<=r;i++) d[++len]=c[i].l,d[++len]=c[i].r;
sort(d+1,d+1+len);
len=unique(d+1,d+1+len)-d-1;
for(int i=1;i<=len;i++) num[d[i]]=i,sum[i]=0;
for(int i=l;i<=r;i++) sum[num[c[i].l]]++,sum[num[c[i].r]]--;
for(int i=1;i<=len;i++) sum[i]+=sum[i-1];
for(int i=1;i<len;i++) ans+=(sum[i]&1)*(d[i+1]-d[i]);
r++;l=r;
}
return;
}
int main()
{
LL q=read();
for(int i=1;i<=q;i++)
{
int x1=read(),y1=read(),x2=read()+1,y2=read()+1;
add1(x1,y1,y2);add2(y1,x1,x2);
add1(x2,y1,y2);add2(y2,x1,x2);
}
sort(a+1,a+1+cnt,cmp);sort(b+1,b+1+cnt,cmp);
ask(a);ask(b);
cout<<ans;
return 0;
}