https://www.acwing.com/solution/content/135911/
放个模板先
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define re register
#define int ll
#define PII pair<int,int>
int read()
{
int f=1,k=0;char c = getchar();
while(c <'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')k=(k<<1)+(k<<3)+(c^48),c=getchar();
return k*f;
}
const int N = 8e5+5; //数组尽量开大点 16倍
int n;
vector<int> v;
struct node
{
int x,y1,y2,k; //存储一条竖着的边
}a[N];
struct tree
{
int len = 0,cnt = 0;
}t[N];
bool cmp(node a,node b)
{
return a.x < b.x;
}
int tot;
int find(int x)
{
return lower_bound(v.begin(),v.end(),x) - v.begin() + 1;
}
void pushup(int k ,int l,int r)
{
if (t[k].cnt) t[k].len = v[r+1 - 1] - v[l - 1]; // cnt > 0表示该区间已完全覆盖,len改为区间长度
else t[k].len = t[k<<1].len + t[k<<1|1].len; //没有完全覆盖则从子节点获取len
}
void modify(int k,int l,int r,int x,int y,int v)
{
if (x > r || y < l) return;
if (x <= l && r <= y)
{
t[k].cnt += v;
pushup(k,l,r); //当cnt变化时,len也会变, 因此这里也需要pushup
return;
}
int mid = (l +r) >> 1;
modify(k<<1,l,mid,x,y,v);
modify(k<<1|1,mid + 1,r,x,y,v);
pushup(k,l,r); // 正常pushup
}
signed main()
{
cin >> n;
for (int i = 1;i <= n;i++)
{
int x1 = read(),y1 = read(),x2 = read(),y2 = read();
a[++tot] = {x1,y1,y2,1}; //入边 -> 1
a[++tot] = {x2,y1,y2,-1};//出边 -> -1
v.push_back(y1);v.push_back(y2);
}
sort(v.begin(),v.end());
sort(a + 1,a + tot + 1,cmp);
v.erase(unique(v.begin(),v.end()),v.end()); //离散化
int ans = 0;
for (int i = 1;i <= tot;i++)
{
ans += (a[i].x-a[i-1].x) * t[1].len; //长 x 宽
modify(1,1,v.size(),find(a[i].y1),find(a[i].y2)-1,a[i].k);//r-1是因为对应的区间下标少1
}
cout << ans << endl;
return 0;
}
标签:begin,end,int,len,算法,扫描线,随笔,define
From: https://www.cnblogs.com/codwarm/p/18318874