題意:求矩陣面積並(注意座標是浮點)
題解:因爲座標是浮點,所以需要離散化。然後重點在於離散化之後的工作,即把每條矩形看成兩條線段,從下往上掃描。每次掃到矩形的下邊就把區間+1,上邊爲區間-1,然後每次的面積就是非零區間的長度*兩條掃描線之間的高度,加起來就可以
區間修改要用到線段樹優化
具體圖片流程可以看這裏
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 2000+5;
const int mod = 998244353;
struct edge {
double l,r,h;
int f;
edge(){}
edge(double tl,double tr,double th,int tf){
l=tl;r=tr;h=th;f=tf;
}
bool operator <(const edge &rhs)const {
return h<rhs.h;
}
}a[maxn];
double X[maxn],sum[maxn<<2];int tag[maxn<<2];
void init(){
memset(sum,0,sizeof(sum));
memset(tag,0,sizeof(tag));
}
void push_up(int rt,int l,int r){
if(tag[rt])sum[rt]=X[r+1]-X[l];
else if(l==r)sum[rt]=0;
else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int L,int R,int c,int rt,int l,int r){
if(L<=l&&r<=R){
tag[rt]+=c;
push_up(rt,l,r);
return ;
}
int mid=(l+r)>>1;
if(L<=mid)update(L,R,c,rt<<1,l,mid);
if(R>mid)update(L,R,c,rt<<1|1,mid+1,r);
push_up(rt,l,r);
}
int main()
{
int n,kase=0;
while(scanf("%d",&n)!=EOF&&n){
int cnt=0;
for(int i=0;i<n;i++){
double xa,ya,xb,yb;
scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
a[++cnt]=edge(xa,xb,yb,1);
X[cnt]=xa;
a[++cnt]=edge(xa,xb,ya,-1);
X[cnt]=xb;
}
sort(X+1,X+cnt+1);
sort(a+1,a+cnt+1);
int m=unique(X+1,X+cnt+1)-X-1;
init();
double ans=0;
for(int i=1;i<=cnt-1;i++){
int l=lower_bound(X+1,X+m+1,a[i].l)-X;
int r=lower_bound(X+1,X+m+1,a[i].r)-X;
update(l,r-1,1.0*a[i].f,1,1,m);
ans+=sum[1]*(a[i+1].h-a[i].h);
//cout<<ans<<endl;
}
printf("Test case #%d\nTotal explored area: ",++kase);
printf("%.2f\n",ans);
printf("\n");
}
return 0;
}