线段树求矩形面积和,模板题(数据全部为整数)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX 10010 #define LCH(n) ((n)<<1) #define RCH(n) ((n)<<1|1) struct segment { int l,r,h,f; }ss[2*MAX]; struct node { int l,r,cnt,len; int mid() { return (l+r)>>1; } }tt[2*MAX*4]; int pos[2*MAX]; int nums; int cmp(struct segment p ,struct segment q) { return p.h<q.h; } void build(int a ,int b ,int rt) { tt[rt].l=a; tt[rt].r=b; tt[rt].cnt=0; tt[rt].len=0; if(tt[rt].l==tt[rt].r) return ; int mid=tt[rt].mid(); build(a,mid,LCH(rt)); build(mid+1,b,RCH(rt)); } int binary(int key ,int low ,int high) { while(low<=high) { int mid=(low+high)>>1; if(key==pos[mid]) return mid; else if(key<pos[mid]) high=mid-1; else low=mid+1; } return -1; } void cal(int rt) { if(tt[rt].cnt) tt[rt].len= pos[tt[rt].r+1]-pos[tt[rt].l]; else if(tt[rt].l==tt[rt].r) tt[rt].len=0; else tt[rt].len=tt[LCH(rt)].len + tt[RCH(rt)].len; } void updata(int a, int b ,int val ,int rt) { if(tt[rt].l==a && tt[rt].r==b) //目标区间 { tt[rt].cnt += val; cal(rt); return ; } int mid=tt[rt].mid(); if(b<=mid) updata(a,b,val,LCH(rt)); else if(a>mid) updata(a,b,val,RCH(rt)); else { updata(a,mid,val,LCH(rt)); updata(mid+1,b,val,RCH(rt)); } cal(rt); } int main() { int n; while(scanf("%d",&n)!=EOF) { nums=0; for(int i=0; i<n; i++) { int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ss[nums].l=x1; ss[nums].r=x2; ss[nums].h=y1; ss[nums].f=1; ss[nums+1].l=x1; ss[nums+1].r=x2; ss[nums+1].h=y2; ss[nums+1].f=-1; pos[nums]=x1; pos[nums+1]=x2; nums+=2; } sort(ss,ss+nums,cmp); sort(pos,pos+nums); int m=1; for(int i=1; i<nums; i++) if(pos[i]!=pos[i-1]) pos[m++]=pos[i]; build(0,m-1,1); long long ans=0; for(int i=0; i<nums-1; i++) { int l=binary(ss[i].l,0,m-1); int r=binary(ss[i].r,0,m-1)-1; updata(l,r,ss[i].f,1); ans += tt[1].len*(ss[i+1].h-ss[i].h); //printf("%lld\n",ans); } printf("%lld\n",ans); } }