题目
思路
主要是这里的线段树要搞清楚只能查询区间
[
1
,
q
]
[1,q]
[1,q] (最大的区间)
这里的标记不下传的特殊性
因为要解决
次
数
≥
2
次数\ge 2
次数≥2 很难进行区间减操作
u
.
s
1
:
u.s_1:
u.s1: 只考虑
u
u
u 子树内恰好被覆盖一次长度
u
.
s
2
:
u.s_2:
u.s2: 只考虑
u
u
u 子树内被覆盖至少两次长度
更新如下
void PushUp(int u){//有点不严谨,没有考虑叶节点赋值情况
if(t[u].cnt>=2)
t[u].s1=t[u].s2=t[u].s0;
else if(t[u].cnt==1){
t[u].s1=t[u].s0;
t[u].s2=t[lch].s1+t[rch].s1;
}
else{
t[u].s1=t[lch].s1+t[rch].s1;
t[u].s2=t[lch].s2+t[rch].s2;
}
return ;
}
代码
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<cstdio>
#include<queue>
#include<vector>
#include<climits>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
int read(){
int f=1,x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x*f;
}
const int MAXN=100000;
const int INF=0x3f3f3f3f;
struct node{
int cnt;
double s0,s1,s2;
}t[5*MAXN+5];
#define lch (u<<1)
#define rch (u<<1|1)
struct mo{int l,r,c;};
vector<mo> G[MAXN+5];
double X1[MAXN+5],X2[MAXN+5],Y1[MAXN+5],Y2[MAXN+5];
double Dx[2*MAXN+5],Dy[2*MAXN+5];
void BS(double *A,int len,double &x){
int L=1,R=len+1;
while(L+1<R){
int Mid=(L+R)>>1;
if(A[Mid]<=x) L=Mid;
else R=Mid;
}
x=L;
return ;
}
double val[MAXN+5];
void PushUp(int u){
if(t[u].cnt>=2)
t[u].s1=t[u].s2=t[u].s0;
else if(t[u].cnt==1){
t[u].s1=t[u].s0;
t[u].s2=t[lch].s1+t[rch].s1;
}
else{
t[u].s1=t[lch].s1+t[rch].s1;
t[u].s2=t[lch].s2+t[rch].s2;
}
return ;
}
void Build(int u,int L,int R){
t[u]=(node){0,Dy[R+1]-Dy[L],0,0};
if(L==R) return ;
int Mid=(L+R)>>1;
Build(lch,L,Mid),Build(rch,Mid+1,R);
PushUp(u);
return ;
}
void Modify(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)
Modify(lch,L,Mid,qL,qR,p);
if(Mid+1<=qR)
Modify(rch,Mid+1,R,qL,qR,p);
PushUp(u);
return ;
}
int main(){
int T=read();
while(T--){
int n=read();
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&X1[i],&Y1[i],&X2[i],&Y2[i]);
Dx[(i<<1)-1]=X1[i],Dx[(i<<1)]=X2[i],Dy[(i<<1)-1]=Y1[i],Dy[(i<<1)]=Y2[i];
}
sort(Dx+1,Dx+2*n+1);
sort(Dy+1,Dy+2*n+1);
int p=unique(Dx+1,Dx+2*n+1)-(Dx+1);
int q=unique(Dy+1,Dy+2*n+1)-(Dy+1);
for(int i=1;i<=n;i++){
BS(Dx,p,X1[i]),BS(Dx,p,X2[i]);
BS(Dy,q,Y1[i]),BS(Dy,q,Y2[i]);
G[(int)X1[i]].push_back((mo){(int)Y1[i],(int)Y2[i]-1,1});
G[(int)X2[i]].push_back((mo){(int)Y1[i],(int)Y2[i]-1,-1});
}
Build(1,1,q-1);
double ans=0;
for(int i=1;i<=p;i++){
ans+=(Dx[i]-Dx[i-1])*t[1].s2;
for(int j=0;j<(int)G[i].size();j++)
Modify(1,1,q-1,G[i][j].l,G[i][j].r,G[i][j].c);
}
for(int i=1;i<=p;i++)
G[i].clear();
printf("%.2f\n",ans);
}
return 0;
}
/*
1
2
1 2 3 4
2 1 4 3
*/