洛谷P4148 简单题

线段树+分块

对x轴分块,每个块和每一列维护个动态开点线段树

每次插入时插入到对应的列和块里

这样时空复杂度都高,发现对于子树大小为1的节点,可以存进lazy里

insert时遇到没开的点就放下lazy然后return,遇到lazy就pushdown

query的话不必pushdown,因为存在lazy的点下边就没东西了,判断是否在查询范围内然后乘上贡献return

#include<bits/stdc++.h>
using namespace std;
struct tree{
	int lc,rc;
	int sum;
	int lazy;
}tre[(int)2e6];
int n,tot;
int size;
int root[(int)5e5+11],rot[711];
inline int read()
{
	int s=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s;
}
void pushdown(int i,int mid)
{
	if(tre[i].lazy<=mid)
	{
		if(!tre[i].lc) tre[i].lc=++tot;
		tre[tre[i].lc].sum=tre[i].sum;
		tre[tre[i].lc].lazy=tre[i].lazy;
		tre[i].lazy=0;
	}
	else
	{
		if(!tre[i].rc) tre[i].rc=++tot;
		tre[tre[i].rc].sum=tre[i].sum;
		tre[tre[i].rc].lazy=tre[i].lazy;
		tre[i].lazy=0;
	}
	return;
}
void insert(int &i,int l,int r,int x,int val)
{
	if(!i) {i=++tot;tre[i].lazy=x;tre[i].sum=val;return;};
	if(tre[i].lazy)pushdown(i,(l+r)/2);tre[i].sum+=val;
	if(l==r) return;
	int mid=(l+r)>>1;
	if(x<=mid) insert(tre[i].lc,l,mid,x,val);
	else insert(tre[i].rc,mid+1,r,x,val);
	return;
}
int query(int i,int l,int r,int x,int y)
{
	if(tre[i].lazy) return (tre[i].lazy>=x&&tre[i].lazy<=y)*tre[i].sum;
	if(!i) return 0;
	if(l>=x&&r<=y) return tre[i].sum;
	int mid=(l+r)>>1;
	int ans=0;
	if(x<=mid) ans+=query(tre[i].lc,l,mid,x,y);
	if(y>mid) ans+=query(tre[i].rc,mid+1,r,x,y);
	return ans;
}
int main()
{
	n=read();
	int ty,ans=0,l,r;
	size=sqrt(n)*1.5+2;
	int x,y,w;
	int xp,yp,xd,yd,i;
	while((ty=read())!=3)
	{
		ans=0;
		if(ty==1)
		{
			x=read()^ans;
			y=read()^ans;
			w=read()^ans;
			insert(root[y],1,n,x,w);
			insert(rot[y/size+1],1,n,x,w);
		}
		else
		{
			xd=read()^ans,yd=read()^ans;
			xp=read()^ans,yp=read()^ans;
			ans=0;
			l=yd/size+1;
			r=yp/size+1;
			if(l==r)
			{
				for(i=yd;i<=yp;i++) ans+=query(root[i],1,n,xd,xp);
				printf("%d\n",ans);
				continue;
			}
			for(i=yd;i/size+1==l;i++) ans+=query(root[i],1,n,xd,xp);
			for(i=l+1;i<r;i++) ans+=query(rot[i],1,n,xd,xp);
			for(i=yp;i/size+1==r;i--) ans+=query(root[i],1,n,xd,xp);
			printf("%d\n",ans);
		}
	}
	return 0;
}
posted @ 2021-10-08 17:02  sitiy  阅读(20)  评论(0编辑  收藏  举报