题目
思路
扫描线后可知道周长发生变化时导致覆盖长度变化
线段树维护覆盖长度横竖两次即可
标记永久化管理本区间
注意离散化可能
+
+
−
−
++--
++−− 算重
还可以不用算两次,维护线段个数
贡献为
2
∗
c
n
t
∗
Δ
y
+
Δ
c
o
v
2*cnt*\Delta_y+\Delta_{cov}
2∗cnt∗Δy+Δcov
代码
#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<cstdio>
#include<queue>
#include<cmath>
#include<vector>
#include<cstring>
#include<climits>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
int read(){
int f=1,x=0;char c=getchar();
while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}
while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}
return f*x;
}
#define lch (u<<1)
#define rch (u<<1|1)
const int MAXN=200000;
const int INF=0x3f3f3f3f;
struct node{
int l,r,len,cnt,s,t;
}t[4*MAXN+5];
int X[MAXN+5],Y[MAXN+5];
void PushUp(int u){
if(t[u].cnt) t[u].s=t[u].len,t[u].t=t[u].r-t[u].l+1-t[lch].t-t[rch].t;
else t[u].s=t[lch].s+t[rch].s,t[u].t=t[lch].t+t[rch].t;
return ;
}
void Build(int u,int L,int R){
t[u]=(node){L,R,X[R+1]-X[L],0,0,0};
if(L==R) return ;
int Mid=(L+R)>>1;
Build(lch,L,Mid),Build(rch,Mid+1,R);
PushUp(u);
return ;
}
void Modi(int u,int L,int R,int qL,int qR,int p){
if(qL<=L&&R<=qR){
t[u].cnt+=p,PushUp(u);
return ;
}
int Mid=(L+R)>>1;
if(qL<=Mid) Modi(lch,L,Mid,qL,qR,p);
if(Mid+1<=qR) Modi(rch,Mid+1,R,qL,qR,p);
PushUp(u);
return ;
}
struct ad{int l,r,p;};
vector<ad> G[MAXN+5];
int tx1[MAXN+5],ty1[MAXN+5],tx2[MAXN+5],ty2[MAXN+5];
int X1[MAXN+5],Y1[MAXN+5],X2[MAXN+5],Y2[MAXN+5];
int main(){
int n;
while(~scanf("%d",&n)&&n){
int p=0,q=0;
for(int i=1;i<=n;i++){
tx1[i]=X1[i]=read(),ty1[i]=Y1[i]=read(),tx2[i]=X2[i]=read(),ty2[i]=Y2[i]=read();
X[++p]=X1[i],X[++p]=X2[i],Y[++q]=Y1[i],Y[++q]=Y2[i];
}
sort(X+1,X+p+1);
sort(Y+1,Y+q+1);
p=unique(X+1,X+p+1)-(X+1);
q=unique(Y+1,Y+q+1)-(Y+1);
for(int i=1;i<=n;i++){
X1[i]=lower_bound(X+1,X+p+1,X1[i])-X;
X2[i]=lower_bound(X+1,X+p+1,X2[i])-X;
Y1[i]=lower_bound(Y+1,Y+q+1,Y1[i])-Y;
Y2[i]=lower_bound(Y+1,Y+q+1,Y2[i])-Y;
G[Y1[i]].push_back((ad){X1[i],X2[i]-1,1});
G[Y2[i]].push_back((ad){X1[i],X2[i]-1,-1});
}
Build(1,1,p-1);
int ans=0,lst=0;
for(int i=1;i<=q;i++){
//ans+=(Y[i]-Y[i-1])*t[1].t;
for(int j=0;j<(int)G[i].size();j++){
Modi(1,1,p-1,G[i][j].l,G[i][j].r,G[i][j].p);
ans+=abs(lst-t[1].s),lst=t[1].s;
}
G[i].clear();
}
p=0,q=0;
for(int i=1;i<=n;i++){
X1[i]=ty1[i],Y1[i]=tx1[i],X2[i]=ty2[i],Y2[i]=tx2[i];
X[++p]=X1[i],X[++p]=X2[i],Y[++q]=Y1[i],Y[++q]=Y2[i];
}
sort(X+1,X+p+1);
sort(Y+1,Y+q+1);
p=unique(X+1,X+p+1)-(X+1);
q=unique(Y+1,Y+q+1)-(Y+1);
for(int i=1;i<=n;i++){
X1[i]=lower_bound(X+1,X+p+1,X1[i])-X;
X2[i]=lower_bound(X+1,X+p+1,X2[i])-X;
Y1[i]=lower_bound(Y+1,Y+q+1,Y1[i])-Y;
Y2[i]=lower_bound(Y+1,Y+q+1,Y2[i])-Y;
G[Y1[i]].push_back((ad){X1[i],X2[i]-1,1});
G[Y2[i]].push_back((ad){X1[i],X2[i]-1,-1});
}
Build(1,1,p-1);
lst=0;
for(int i=1;i<=q;i++){
//ans+=(Y[i]-Y[i-1])*t[1].t;
for(int j=0;j<(int)G[i].size();j++){
Modi(1,1,p-1,G[i][j].l,G[i][j].r,G[i][j].p);
ans+=abs(lst-t[1].s),lst=t[1].s;
}
G[i].clear();
}
printf("%d\n",ans);
}
return 0;
}