fzu-2105 (segmento intervalo de actualización de árbol)

Significado de las preguntas: intervalo tiene tres operaciones binarias, el rango de valores de no más de 16, y luego intervalo de consulta. Puesto que cada número es pequeño, por lo que un gran número de duplicados en la sección de memoria, y después del intervalo de funcionamiento igual al valor binario más y más. Tan sólo hay que registrar el valor actual es igual al intervalo.

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int tree[1000000*4];
int a[1000000];
void push_down(int l,int r,int k)
{
	if(tree[k<<1]!=-1&&tree[k<<1|1]==tree[k<<1])
	{
		tree[k]=tree[k<<1];
	}
}
void build(int l,int r,int k)
{
	tree[k]=-1;
	if(l==r)
	{
		tree[k]=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,k<<1);
	build(mid+1,r,k<<1|1);
	push_down(l,r,k);
}
void update(int L,int R,int l,int r,int k,int flag,int val)
{
	int mid=(L+R)>>1;
	if(L>=l&&R<=r&&tree[k]!=-1)
	{
		if(flag==1)tree[k]^=val;
		else if(flag==2)tree[k]|=val;
		else if(flag==3)tree[k]&=val;
		return ;
	}
	if(tree[k]>=0)		//下传标记 
	{
		tree[k<<1]=tree[k<<1|1]=tree[k];tree[k]=-1;
	}
	if(l<=mid) update(L,mid,l,r,k<<1,flag,val);
	if(r>mid) update(mid+1,R,l,r,k<<1|1,flag,val);
	push_down(L,R,k);//上传标记 
}
int query(int L,int R,int l,int r,int k)
{
	int ans=0;
	int mid=(L+R)>>1;
	if(L>=l&&R<=r&&tree[k]!=-1)
	{
		return tree[k]*(R-L+1);
	}
	if(tree[k]>=0)		//下传标记 
	{
		tree[k<<1]=tree[k<<1|1]=tree[k];tree[k]=-1;
	}
	if(l<=mid)
	ans+=query(L,mid,l,r,k<<1);
	if(r>mid)
	ans+=query(mid+1,R,l,r,k<<1|1);
	push_down(L,R,k);//上传标记
	return ans;
}
int main()
{
	int t;scanf("%d",&t);
	while(t--)
	{
		int n,q;
		scanf("%d%d",&n,&q);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		build(1,n,1);
		while(q--)
		{
			char s[5];int x,y,z;
			scanf("%s",s);
			if(s[0]=='S')
			{
				scanf("%d%d",&x,&y);x++;y++;
				printf("%d\n",query(1,n,x,y,1));
			}
			else if(s[0]=='X')
			{
				scanf("%d%d%d",&z,&x,&y);x++;y++;
				update(1,n,x,y,1,1,z);		//orx
			}
			else if(s[0]=='O')
			{
				scanf("%d%d%d",&z,&x,&y);x++;y++;
				update(1,n,x,y,1,2,z);		//or
			}
			else
			{
				scanf("%d%d%d",&z,&x,&y);x++;y++;			//and
				update(1,n,x,y,1,3,z);
			}
		}
	}
	
	return 0;
}

 

Publicados 155 artículos originales · ganado elogios 32 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/qq_37632935/article/details/88820163
Recomendado
Clasificación