题意:有n排板砖,m个木板,边界的l和r的n列板砖从天上掉下来,然后有m个边界的a,b的高度为h的木板去接那些板砖,一排板砖中的部分板砖如果掉到木板上就停止下落,剩下的继续下落,问最后每块木板上有多少块板砖。
开结构体去存储线段树中节点的信息MLE了。。
按木板的高度,从低到高,去更新线段树节点对应的木板的编号。
板砖落下时,将对应区间的覆盖次数加一。
最后查询的时候,如果已经是叶子结点,或者这个区间的对应的木板的编号是确定的,那么就要在对应的木板编号上加上,覆盖次数乘以区间长度的值。
#include <iostream> #include <cstdio> #include <cstring> #include <map> #include <vector> #include <algorithm> using namespace std; typedef long long LL; const int N=100005; #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) vector<int> Y; map<int,int> H; LL ans[N]; int l[N],r[N]; struct BOARD { int x,y,h,ind; void get() { scanf("%d%d%d",&x,&y,&h); Y.push_back(x); Y.push_back(y); } bool operator<(const BOARD &b)const { return h<b.h; } }board[N]; struct Segtree { int color[N*4*4],sum[N*4*4]; void PushDown(int ind) { if(color[ind]) { color[LL(ind)]=color[ind]; color[RR(ind)]=color[ind]; color[ind]=0; } if(sum[ind]) { sum[LL(ind)]+=sum[ind]; sum[RR(ind)]+=sum[ind]; sum[ind]=0; } } void build(int ind,int lft,int rht) { memset(color,0,sizeof(color)); memset(sum,0,sizeof(sum)); } void updata_color(int st,int ed,int col,int ind,int lft,int rht) { if(st<=lft&&rht<=ed) color[ind]=col; else { PushDown(ind); int mid=MID(lft,rht); if(st<mid) updata_color(st,ed,col,LL(ind),lft,mid); if(ed>mid) updata_color(st,ed,col,RR(ind),mid,rht); } } void updata_sum(int st,int ed,int ind,int lft,int rht) { if(st<=lft&&rht<=ed) sum[ind]+=1; else { PushDown(ind); int mid=MID(lft,rht); if(st<mid) updata_sum(st,ed,LL(ind),lft,mid); if(ed>mid) updata_sum(st,ed,RR(ind),mid,rht); } } void query(int ind,int lft,int rht) { if(lft+1==rht||color[ind]) { if(color[ind]) ans[color[ind]]+=(LL)sum[ind]*(Y[rht]-Y[lft]); } else { PushDown(ind); int mid=MID(lft,rht); query(LL(ind),lft,mid); query(RR(ind),mid,rht); } } }seg; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { Y.clear(); H.clear(); memset(ans,0,sizeof(ans)); for(int i=0;i<n;i++) { scanf("%d%d",&l[i],&r[i]); Y.push_back(l[i]); Y.push_back(r[i]); } for(int i=0;i<m;i++) board[i].get(),board[i].ind=i+1; sort(Y.begin(),Y.end()); Y.erase(unique(Y.begin(),Y.end()),Y.end()); int len=(int)Y.size(); for(int i=0;i<len;i++) H[Y[i]]=i; sort(board,board+m); seg.build(1,0,len-1); for(int i=0;i<m;i++) { seg.updata_color(H[board[i].x],H[board[i].y],board[i].ind,1,0,len-1); } for(int i=0;i<n;i++) { seg.updata_sum(H[l[i]],H[r[i]],1,0,len-1); } seg.query(1,0,len-1); for(int i=1;i<=m;i++) printf("%lld\n",ans[i]); puts(""); } return 0; }