[CSP校内集训]矩形面积交(树状数组)

题意

(n)个互不相交的矩形,再给(m)个询问,每次给一个矩形求它与这(n)个矩形的面积交

思路

自己写的太丑了导致DEBUG了一个半小时qwq

一对矩形的交可以拆分成二维前缀和形式下的矩形的交,于是变成判断16次矩形的交(不想画图...只想口胡)

这些矩形都有(x_0=0,y_0=0),即左下角为坐标原点,于是一个矩形可以只用右上角的坐标表示;

对于一个询问的矩形((x,y))和另一个矩形((x_i,y_i)),它们的交为(min(x,x_i) imes min(y,y_i))

(x)排序,分类讨论(yleq y_i)(y>y_i),用树状数组维护即可

Code

#include<bits/stdc++.h>
#define N 500005
#define int ll
#define lowbit(x) ((x)&(-(x)))
#define Min(x,y) ((x)<(y)?(x):(y))
#define Max(x,y) ((x)>(y)?(x):(y))
using namespace std;
typedef long long ll;
int n,m,w,l,cnt0,cnt;
ll sum[N],sumy[N],sumx[N],c[N];
struct Matrix { int x,y,opt; } ma[N<<2];
struct Query { int x,y,id,opt; ll ans; } q[N<<2];

template <class T>
void read(T &x)
{
	char c; int sign=1;
	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
	while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
}
void ad(int id,int opt,int x,int y)
{
	++cnt;
	q[cnt].id=id; q[cnt].opt=opt;
	q[cnt].x=x; q[cnt].y=y;	
}
void modify_1(int x,int val) { for(;x<N;x+=lowbit(x)) c[x]+=val; }
void modify_2(int x,ll val) { for(;x<N;x+=lowbit(x)) sum[x]+=val; }
void modify_3(int x,ll val) { for(;x<N;x+=lowbit(x)) sumy[x]+=val; }
void modify_4(int x,ll val) { for(;x<N;x+=lowbit(x)) sumx[x]+=val; } 
ll query_1(int x) { ll ret=0; for(;x;x-=lowbit(x)) ret+=c[x]; return ret;}
ll query_2(int x) { ll ret=0; for(;x;x-=lowbit(x)) ret+=sum[x]; return ret;}
ll query_3(int x) { ll ret=0; for(;x;x-=lowbit(x)) ret+=sumy[x]; return ret;}
ll query_4(int x) { ll ret=0; for(;x;x-=lowbit(x)) ret+=sumx[x]; return ret;} 
void update(Matrix a)//加入矩阵a 
{
	modify_1(a.y,a.opt);
	modify_2(a.y,a.opt*(a.x*a.y));
	modify_3(a.y,a.opt*a.y);
	modify_4(a.y,a.opt*a.x);
}
bool cmp1(Matrix a,Matrix b) { return a.x<b.x; }
bool cmp2(Query a,Query b) { return a.x<b.x; }
bool cmp3(Query a,Query b) { return a.id<b.id; }
signed main()
{
	freopen("intersec.in","r",stdin);
	freopen("intersec.out","w",stdout);
	read(n);read(m);read(w);read(l);
	for(int i=1;i<=n;++i)
	{
		int x[2],y[2];
		read(x[0]);read(y[0]);
		read(x[1]);read(y[1]);
		ma[++cnt0]=(Matrix){x[1],y[1],1};
		ma[++cnt0]=(Matrix){x[0],y[1],-1};
		ma[++cnt0]=(Matrix){x[1],y[0],-1};
		ma[++cnt0]=(Matrix){x[0],y[0],1};
	}
	for(int i=1;i<=m;++i)
	{
		int x[2],y[2];
		read(x[0]);read(y[0]);
		read(x[1]);read(y[1]);
		ad(i,1,x[1],y[1]);
		ad(i,-1,x[0],y[1]);
		ad(i,-1,x[1],y[0]);
		ad(i,1,x[0],y[0]);
	}
	sort(ma+1,ma+cnt0+1,cmp1);
	sort(q+1,q+cnt+1,cmp2);
	int L=0;//加入了L个矩阵 
	for(int i=1;i<=cnt;++i)//处理第i个询问矩阵 
	{
		if(q[i].x==0||q[i].y==0) continue;
		while(L<cnt0&&ma[L+1].x<=q[i].x)
		{
			++L;
			if(ma[L].x>0&&ma[L].y>0) update(ma[L]);
		}
		q[i].ans+=(query_2(q[i].y) + q[i].y*(query_4(N-1)-query_4(q[i].y)));
	}
	
	memset(c,0,sizeof(c));
	memset(sum,0,sizeof(sum));
	memset(sumx,0,sizeof(sumx));
	memset(sumy,0,sizeof(sumy));
	int R=cnt0+1;
	for(int i=cnt;i>=1;--i)
	{
		if(q[i].x==0||q[i].y==0) continue;
		while(R>1&&ma[R-1].x>q[i].x)
		{
			--R;
			if(ma[R].x>0&&ma[R].y>0) update(ma[R]);
		}
		q[i].ans+=q[i].x * (query_3(q[i].y) + (query_1(N-1)-query_1(q[i].y))*q[i].y);
	}
	sort(q+1,q+cnt+1,cmp3);
	for(int i=1;i<=cnt;i+=4)
	{
		ll ans=0;
		for(int j=0;j<4;++j) ans+=q[i+j].opt*q[i+j].ans;
		printf("%lld
",ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Chtholly/p/11782389.html