典型的(对我来说不典型)的多边形的并
通用算法:扫描线+链表
不断往上扫描并且利用一个cover数组暴力改
然后用链表维护添加和删除
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1e6+100;
struct Triangle{
int x,y,d,l,r;
friend bool operator <(Triangle A,Triangle B){
return A.y<B.y;
}
}T[N];
int n;
int mx=-1;
int pre[N]={};
int nxt[N]={};
void Del(int x){
pre[nxt[x]]=pre[x];
nxt[pre[x]]=nxt[x];
}
void Ins(int x,int y){
pre[nxt[x]]=y;
nxt[y]=nxt[x];
pre[y]=x;
nxt[x]=y;
}
int head,tail,nowh;
int cover[N]={};
bool ins(int x){
if(!T[x].d)return false;
for(int i=nxt[head];i!=tail;i=nxt[i]){
if(T[i].x<=T[x].x&&T[x].x+T[x].d-1<=T[i].x+T[i].d-1-(T[i].d-nowh))return false;
}
Ins(head,x);
return true;
}
int main(){
// freopen("2031.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&T[i].x,&T[i].y,&T[i].d);
mx=max(mx,T[i].y+T[i].d);
T[i].l=T[i].x;
T[i].r=T[i].x+T[i].d-1;
// cout<<"here"<<'\n';
}
sort(T+1,T+1+n);
// cout<<"here";
int ans=0;
head=0;
tail=n+1;
pre[nxt[head]=tail]=head;
// cout<<"here"<<'\n';
int last=0;
int j=1;
// cout<<"here"<<'\n';
for(int i=T[1].y;i<=mx;i++){
// cout<<i<<" "<<'\n';
int now=last;
for(int k=nxt[head];k!=tail;k=nxt[k]){
cover[T[k].r]--;
if(!cover[T[k].r])now--;
T[k].r--;
if(T[k].r<T[k].l)Del(k);
}
ans+=now+last;
while(j<=n&&T[j].y==i){
if(ins(j)){
for(int k=T[j].x;k<T[j].x+T[j].d;k++){
if(!cover[k])now++;
cover[k]++;
}
}
j++;
}
last=now;
}
printf("%.1lf",ans/2.0);
}