我是看的第二篇题解。
我写的代码:
#include <bits/stdc++.h>
using namespace std;
namespace Main
{
typedef long long ll;
typedef __int128 ll128;
const int maxn=1e5+5;
struct OD
{
int x,y1,y2;
int flag;//权值
//x是纵线的横坐标,y1是下纵坐标,y2是上纵坐标
}od[maxn<<1],lsh[maxn<<1];
//od存储原始读入的竖线信息,lsh存储横坐标不变,纵坐标离散化之后的信息
int n;
int h_rem[maxn<<1];//暂时存储纵坐标相关信息
inline bool cmp(OD a,OD b)
{
return (a.x!=b.x)?(a.x<b.x):(a.flag>b.flag);
}
struct Tree
{
int l,r,ls,rs,len,lazy;
}tree[maxn*16];//nlogn*2
int val[maxn<<1];
int ncnt;
inline int ls(int i)
{
return tree[i].ls;
}
inline int rs(int i)
{
return tree[i].rs;
}
inline int len(int i)
{
return tree[i].r-tree[i].l+1;
}
inline void add(int i,int val)
{
tree[i].lazy+=val;
}
inline void push_up(int i)
{
if(tree[i].lazy)
{
tree[i].len=val[tree[i].r+1]-val[tree[i].l];
return;
}
tree[i].len=tree[ls(i)].len+tree[rs(i)].len;
}
int build(int i,int l,int r)
{
i=++ncnt;
tree[i].l=l,tree[i].r=r;
if(l==r)return i;
int mid=(l+r)>>1;
tree[i].ls=build(ls(i),l,mid);
tree[i].rs=build(rs(i),mid+1,r);
return i;
}
inline void modify(int i,int l,int r,int val)
{
if(tree[i].l>=l&&tree[i].r<=r)
{
add(i,val);
push_up(i);
return;
}
if(tree[i].r<l||tree[i].l>r)return;
int mid=(tree[i].l+tree[i].r)>>1;
if(mid>=l)modify(ls(i),l,r,val);
if(mid<r)modify(rs(i),l,r,val);
push_up(i);
}
void main()
{
scanf("%d",&n);
int x_1,y_1,x_2,y_2;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&x_1,&y_1,&x_2,&y_2);
od[i].x=x_1,od[i].y1=y_1,od[i].y2=y_2,od[i].flag=1;
od[i+n].x=x_2,od[i+n].y1=y_1,od[i+n].y2=y_2,od[i+n].flag=-1;
h_rem[i]=y_1;
h_rem[i+n]=y_2;
}
sort(h_rem+1,h_rem+2*n+1);
int tot=unique(h_rem+1,h_rem+2*n+1)-h_rem-1;
for(int i=1;i<=2*n;i++)
{
lsh[i].x=od[i].x;
lsh[i].flag=od[i].flag;
lsh[i].y1=lower_bound(h_rem+1,h_rem+tot+1,od[i].y1)-h_rem;
lsh[i].y2=lower_bound(h_rem+1,h_rem+tot+1,od[i].y2)-h_rem;
val[lsh[i].y1]=od[i].y1;
val[lsh[i].y2]=od[i].y2;
}
sort(lsh+1,lsh+2*n+1,cmp);
int rt=build(1,1,2*n);//y的排名最多到tot
ll128 ans=0;
for(int i=1;i<2*n;i++)
{
modify(1,lsh[i].y1,lsh[i].y2-1,lsh[i].flag);
ans+=(ll128)tree[1].len*(ll128)(lsh[i+1].x-lsh[i].x);
}
printf("%lld",(ll)ans);
}
}
int main()
{
Main::main();
return 0;
}
为什么第 105 行,要把竖线的上 y 坐标离散化后的值减一再进行修改(lsh[i].y2-1)
为什么第 47 行,push_up 的时候,要先把当前区间的右端点加一再计算(val[tree[i].r+1])