记录编号 344167 评测结果 WWWWWWWWWW
题目名称 2533.[HZOI 2016] 小鱼之美 最终得分 0
用户昵称 FoolMike 是否通过 未通过
代码语言 C++ 运行时间 21.276 s
提交时间 2016-11-09 21:56:49 内存使用 24.29 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=500010;
int T,n,m,X[2][2],x[N][2];
#define lc x<<1
#define rc (x<<1)|1
int tag[N][2],now;
void change(int x,int l,int r,int L,int R,int d1,int d2){
	if (l>=L&&r<=R){tag[x][0]+=d1;tag[x][1]+=d2;return;}
	int mid=(l+r)>>1;
	if (R>mid) change(rc,mid+1,r,L,R,d1,d2);
	if (L<=mid) change(lc,l,mid,L,R,d1,d2);
}
int visit(int x,int l,int r,int p){
	while (l!=r){
		tag[lc][0]+=tag[x][0];
		tag[lc][1]+=tag[x][1];
		tag[rc][0]+=tag[x][0];
		tag[rc][1]+=tag[x][1];
		tag[x][0]=tag[x][1]=0;
		int mid=(l+r)>>1;
		if (p>mid) l=mid+1,x=rc;
			else r=mid,x=lc;
	}
	return x;
}
struct ask{int tp,l,r,x,y;}q[N];
void go_to(int T){
	while (now<T){
		now++;
		if (q[now].tp!=3) change(1,1,n,q[now].l,q[now].r,q[now].x,q[now].y);
	}
	while (now>T){
		if (q[now].tp!=3) change(1,1,n,q[now].l,q[now].r,-q[now].x,-q[now].y);
		now--;
	}
}
int ansl[N],ansr[N],a[N],b[N];
//[l,r]为答案区间,[L,R]为询问区间 
//整体二分,得到鱼在网内的最小时刻和最大时刻 
void solvel(int l,int r,int L,int R){
	if (L>R) return;
	if (l==r){
		for (int i=L;i<=R;i++) ansl[a[i]]=l;
		return;
	}
	int mid=(l+r)>>1,lp=L-1,rp=R+1;
	go_to(mid);
	for (int i=L;i<=R;i++){
		int v=a[i],p=visit(1,1,n,v);
		if (x[v][0]+tag[p][0]>=X[0][0]&&x[v][1]+tag[p][1]>=X[0][1])
			b[++lp]=v;else b[--rp]=v;
	}
	for (int i=L;i<=R;i++) a[i]=b[i];
	solvel(l,mid,L,lp);
	solvel(mid+1,r,rp,R);
}
void solver(int l,int r,int L,int R){
	if (L>R) return;
	if (l==r){
		for (int i=L;i<=R;i++) ansr[a[i]]=l;
		return;
	}
	int mid=(l+r)>>1,lp=L-1,rp=R+1;
	go_to(mid+1);
	for (int i=L;i<=R;i++){
		int v=a[i],p=visit(1,1,n,v);
		if (x[v][0]+tag[p][0]<=X[1][0]&&x[v][1]+tag[p][1]<=X[1][1])
			b[--rp]=v;else b[++lp]=v;
	}
	for (int i=L;i<=R;i++) a[i]=b[i];
	solver(l,mid,L,lp);
	solver(mid+1,r,rp,R);
}
int sum[N];//前缀和 
int main()
{
	freopen("skyfishs.in","r",stdin);
	freopen("skyfishs.out","w",stdout);
	scanf("%d",&T);
	while (T--){
		scanf("%d%d%d%d%d",&n,&X[0][0],&X[0][1],&X[1][0],&X[1][1]);
		for (int i=1;i<=n;i++)
			scanf("%d%d",&x[i][0],&x[i][1]);
		scanf("%d",&m);
		for (int i=1;i<=m;i++){
			scanf("%d%d%d",&q[i].tp,&q[i].l,&q[i].r);
			if (q[i].tp==1) scanf("%d",&q[i].x);
			if (q[i].tp==2) scanf("%d",&q[i].y);
		}
		for (int i=1;i<=n;i++) a[i]=i;
		solvel(0,m,1,n);
		for (int i=1;i<=n;i++) a[i]=i;
		solver(0,m,1,n);
		memset(sum,0,sizeof sum);
		for (int i=1;i<=n;i++)
		if (x[i][0]<=X[1][0]&&x[i][1]<=X[1][1]&&ansl[i]<=ansr[i])
			sum[ansl[i]]++,sum[ansr[i]+1]--;
		for (int i=1;i<=m;i++){
			sum[i]+=sum[i-1];
			if (q[i].tp==3) printf("%d\n",sum[i]);
		}
	}
	return 0;
}