请客官老爷移步:
http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
http://blog.csdn.net/qq_18661257/article/details/47658191
嘻嘻, 大奔 的思路 ;
代码简洁 用的是 区间更新; 而且可以一起求 矩阵的并 与交
两道模板题应用:
一道求交集,一道求并集;
HDU 1264 并集
HDU 1255 交集
【模板代码】:
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
const int MAXN=2000+5;
int col[MAXN<<2],n,cnt,res;
double X[MAXN<<2],Sum[MAXN<<2],Sum2[MAXN<<2];
struct Seg{
double l,r,h;
int flag;
Seg(){}
Seg(double l,double r,double h,int flag):l(l),r(r),h(h),flag(flag){}
bool operator <(const Seg & object ) const{
return h<object.h;
}
}S[MAXN<<2];
void pushup(int rt,int l,int r)
{
if(col[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];
if(col[rt]>=2)// 覆盖两次以上
Sum2[rt]=X[r+1]-X[l];
else if(l==r) Sum2[rt]=0;
else if(col[rt]==1) Sum2[rt]=Sum[rt<<1] +Sum[rt<<1|1];
else if(col[rt]==0) Sum2[rt]=Sum2[rt<<1] +Sum2[rt<<1|1];
}
void update(int L,int R,int c,int rt,int l,int r)// l,r 固定长度 L,R 变化长度
{
if(L<=l&&r<=R)
{
col[rt]+=c;
pushup(rt,l,r);
return;
}
int mid=(l+r)>>1;
if(L<=mid) update(L,R,c,lson);
if(R>mid) update(L,R,c,rson);
pushup(rt,l,r);
}
int binary_find(double x)
{
int lb=-1,ub=res-1;
while(ub-lb>1)
{
int mid=(lb+ub)>>1;
if(X[mid]>=x)ub=mid;
else lb=mid;
}
return ub;
}
double solve(int n)
{
cnt=res=0;
for(int i=0;i<n;i++)
{
double a,b,c,d;
scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
S[cnt]=Seg(a,c,b,1);
X[cnt++]=a;
S[cnt]=Seg(a,c,d,-1);
X[cnt++]=c;
}
sort(X,X+cnt);
sort(S,S+cnt);
res++;
for(int i=1;i<cnt;i++){// 去重
if(X[i]!=X[i-1]) X[res++]=X[i];
}
memset(Sum,0,sizeof(Sum));
memset(col,0,sizeof(col));
memset(Sum2,0,sizeof(Sum2));
double ans=0;
for(int i=0;i<cnt-1;i++)
{
int l=binary_find(S[i].l);//二分左端点,
int r=binary_find(S[i].r)-1; // 左闭右开 二分右端点
update(l,r,S[i].flag,1,0,res-1);
ans+= Sum[1]*(S[i+1].h-S[i].h);// 矩阵并
//ans+= Sum2[1]*(S[i+1].h-S[i].h); //矩阵 交集
}
return ans;
}
123