對于這類面積覆蓋的題,大致就兩點要注意的
1.同一把矩形放在笛卡爾坐標系上做
2.pushup函數要注意下細節:及在統計子區間和之前要先判斷是否有子區間
?
用sum數組來保存區間被覆蓋的情況,如果遇到多次覆蓋問題,那就開多個sum數組分別保存被覆蓋n次的情況
用cnt數組保存區間被完全覆蓋的次數,如果是不同類型的矩形需要分別統計或者有特殊要求,那就開多個cnt數組分別保存
pushup如果cnt[rt]超過了k次,滿足要求,那么就直接把sum[k]賦值為當前區間長度,然后其他sum數組歸零,結束返回
否則如果cnt[rt]不為0,先把所有該區間的sum置零,然后把覆蓋了該區間cnt[rt]次對應的sum賦值為當前區間長度如果rt沒有子區間就返回,有子區間 i 就從1循環到k,如果cnt[rt]+i>=k,那么對應的sum[k]就是兩個子區間的被覆蓋i次的長度和,否則sum[i+cnt[rt]]就是兩個子區間被覆蓋i次的和。結束這次循環后sum[cnt[rt]]還要再減去本區間被覆蓋大于cnt[rt]次對應的sum
最后如果cnt[rt]=0,i從1到k循環,如果沒有子區間,sum就是0,有的話就是子區間的和
?
/* 顏色覆蓋,多了顏色融合,, 用七個sum去記錄七種顏色,三個cnt記錄三種不同顏色的覆蓋 */ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<map> using namespace std; #define maxn 20005 #define lson l,m,rt<<1 #define rson m,r,rt<<1|1 #define ll long long struct Seg{int x,y1,y2,c;Seg(){}Seg(int a,int b,int c,int d):x(a),y1(b),y2(c),c(d){}bool operator<(const Seg & a)const{return x<a.x;} }segs[maxn]; int y[maxn],toty,tot; int sum[maxn<<2][8],cnt[maxn<<2][4]; map<int,int>mp; void pushup(int rt,int l,int r){int tmp=0;if(cnt[rt][1]) tmp|=1;if(cnt[rt][2]) tmp|=2;if(cnt[rt][3]) tmp|=4; //cout << tmp << endl;for(int i=0;i<=7;i++)sum[rt][i]=0;if(tmp){sum[rt][tmp]=y[r]-y[l];for(int i=1;i<=7;i++)if(l+1!=r && tmp!=(tmp|i)){ //如果有更高級的顏色sum[rt][tmp|i]+=sum[rt<<1][i]+sum[rt<<1|1][i];sum[rt][tmp]-=sum[rt<<1][i]+sum[rt<<1|1][i];}}else if(l+1!=r) for(int i=1;i<=7;i++) sum[rt][i]=sum[rt<<1][i]+sum[rt<<1|1][i]; } void update(int L,int R,int c,int l,int r,int rt){if(L<=l && R>=r){ //cout<<c<<endl;if(c>0) cnt[rt][c]+=1;else cnt[rt][-c]-=1;pushup(rt,l,r);return;}int m=l+r>>1;if(L<m) update(L,R,c,lson);if(R>m) update(L,R,c,rson);pushup(rt,l,r); } void init(){tot=toty=0;mp.clear();memset(sum,0,sizeof sum);memset(cnt,0,sizeof cnt); } int main(){int T,x1,x2,y1,y2,c,n;char col[5];cin >> T;for(int tt=1;tt<=T;tt++){init();scanf("%d",&n);for(int i=0;i<n;i++){scanf("%s%d%d%d%d",col,&x1,&y1,&x2,&y2);if(col[0]=='R') c=1;if(col[0]=='G') c=2;if(col[0]=='B') c=3;segs[tot++]=Seg(x1,y1,y2,c);segs[tot++]=Seg(x2,y1,y2,-c);y[toty++]=y1,y[toty++]=y2;}sort(y,y+toty);toty=unique(y,y+toty)-y;for(int i=0;i<toty;i++) mp[y[i]]=i;sort(segs,segs+tot);ll res[8]={};for(int i=0;i<tot;i++){if(i!=0){for(int j=1;j<=7;j++)res[j]+=(ll)(segs[i].x-segs[i-1].x)*sum[1][j];}int y1=mp[segs[i].y1];int y2=mp[segs[i].y2];update(y1,y2,segs[i].c,0,toty-1,1);}printf("Case %d:\n",tt);printf("%lld\n",res[1]);printf("%lld\n",res[2]);printf("%lld\n",res[4]);printf("%lld\n",res[3]);printf("%lld\n",res[5]);printf("%lld\n",res[6]);printf("%lld\n",res[7]);}return 0; }
?