首页 > 其他分享 >cats 的集合 1

cats 的集合 1

时间:2024-08-25 14:17:54浏览次数:8  
标签:case int tot break merge cats 集合 --

  • 0/1 Trie
  • 具象化一次操作对数据结构产生的影响
  • 试想,如果我们在一次修改指令中逐一更新了子树p中的所有节点,但是在之后的查询指令中却根本没有用到,那么更新p的整棵子树就是徒劳的
  • 精妙的懒标记设计,详见代码注释
  • (1ll<60)
  • 用类实现懒标记
  • 无法读取文件是因为UTF-8 BOM,另存为UTF-8就好了
  • 在有操作2、3的情况下,对操作4也要采取同样的处理方法
  • 否则,举个最简单的反例:用3操作清零字典树,之前的异或操作也会失效,不能作用在查询的数上
  • 多测的清空
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int t[400000*31+5][2],tot,T;
const int maxn=(1ll<<31)-1;
//本题的懒标记思想好精妙,以下直接复制了题解的代码, 并尝试对其做出解释
//首先,把对第i层的修改放到根节点上下传,并用二进制数压缩表示 
class LazyTag
{
	public:
		int o,a,x;
		LazyTag()
		{
			o=a=x=0;
		}
		LazyTag(int O,int A,int X)
		{
			o=O;
			a=A;
			x=X;
		}
		void merge(LazyTag &m)
		{
			o^=o&m.a;//and操作抵消or操作 
			a^=a&m.o;//or操作抵消and操作 
			int xx=(o&m.x)|(a&m.x);
			o^=xx;//异或操作抵消or操作,新增and+xor等价的or操作 
			o|=m.o;//合并or操作 
			a^=xx;//异或操作抵消and操作,新增or+xor等价的and操作 
			a|=m.a;//合并and操作 
			x^=((x&m.a)|(x&m.o))^m.x^xx;//更新xor操作 
		} 
		void clean()
		{
			o=a=x=0;
		}
}f[400000*31+5];
void spread(int p,int i);
int merge(int p,int q,int i)
{
	if(!p)
	{
		return q;
	}
	if(!q)
	{
		return p;
	}
	if(i==-1)
	{
		return p;
	}
	spread(p,i);
	spread(q,i);
	t[p][0]=merge(t[p][0],t[q][0],i-1);
	t[p][1]=merge(t[p][1],t[q][1],i-1);
	t[q][0]=t[q][1]=0;
	return p;
}
void insert(int x)
{
	int p=0;
	for(int i=30;i>=0;i--)
	{
		spread(p,i);
		int y=((x>>i)&1);
		if(!t[p][y])
		{
			t[p][y]=++tot;
			f[tot].clean();
			t[tot][0]=t[tot][1]=0;
		}
		p=t[p][y];
	}
}
int ask(int x)
{
	int p=0,ans=0;
	for(int i=30;i>=0;i--)
	{
		spread(p,i);
		int y=(((x>>i)&1)^1);
		if(t[p][y])
		{
			p=t[p][y];
			ans+=(1<<i);
		}
		else
		{
			p=t[p][y^1];
		}
	}
	return ans;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>T;
	while(T--)
	{
		int n,m;
		cin>>n>>m;
		tot=0;
		f[0].clean();
		t[0][0]=t[0][1]=0;
		for(int i=1;i<=n;i++)
		{
			int x;
			cin>>x;
			insert(x);
		}
		for(int i=1;i<=m;i++)
		{
			int opt,x;
			cin>>opt>>x;
			LazyTag tmp1(x,0,0);
			LazyTag tmp2(0,x^maxn,0);
			LazyTag tmp3(0,0,x);
			switch(opt)
			{
				case 1:
					insert(x);
					break;
				case 2:
					f[0].merge(tmp1);
					break;
				case 3:
					f[0].merge(tmp2);
					break;
				case 4:
					f[0].merge(tmp3);
					break;
				case 5:
					cout<<ask(x)<<endl;
					break;
			}
		}
	}
	return 0;
}
void spread(int p,int i)
{
	int o=(f[p].o>>i)&1;
	int a=(f[p].a>>i)&1;
	int x=(f[p].x>>i)&1;
	if(o)
	{
		t[p][1]=merge(t[p][1],t[p][0],i-1);
		t[p][0]=0;
	}
	if(a)
	{
		t[p][0]=merge(t[p][0],t[p][1],i-1);
		t[p][1]=0;
	}
	if(x)
	{
		swap(t[p][0],t[p][1]);
	}
	if(t[p][0])
	{
		f[t[p][0]].merge(f[p]);
	}
	if(t[p][1])
	{
		f[t[p][1]].merge(f[p]);
	}
	f[p].clean();
}

标签:case,int,tot,break,merge,cats,集合,--
From: https://www.cnblogs.com/watersail/p/18377502

相关文章

  • 集合及数据结构第九节————树和二叉树
    系列文章目录集合及数据结构第九节————树和二叉树树和二叉树树型结构的概念树的概念树的表示形式(了解)树的应用二叉树的概念两种特殊的二叉树二叉树的性质二叉树的性质练习二叉树的存储二叉树的遍历二叉树的基本操作二叉树相关练习题文章目录系列文章目录集合及......
  • delphi 里的 in 集合 语法
    在Delphi中,In关键字用于检查一个元素是否存在于一个集合中。这在处理枚举类型或集合类型时非常有用。下面是一个使用In关键字的基本示例,演示如何检查某个值是否属于一个枚举或集合。首先,假设我们有一个枚举类型:typeTDays=(Monday,Tuesday,Wednesday,Thursday,Frid......
  • 从菜鸟到高手:掌握Python推导式,让代码飞起来,列表、集合、字典,一网打尽,用Python推导式
    "在Python的广阔世界里,隐藏着一种让程序员们爱不释手的秘密武器——推导式。想象一下,你正站在数据处理的战场上,面对着成千上万条数据,需要快速筛选、转换、聚合。这时,你手中的列表推导、集合推导、字典推导就像三把锋利的剑,轻轻一挥,便能将复杂的数据操作化繁为简,让代码如同行云......
  • java基础--集合&学生管理系统
    1.ArrayList集合和数组的优势对比:长度可变添加数据的时候不需要考虑索引,默认将数据添加到末尾1.1ArrayList类概述什么是集合提供一种存储空间可变的存储模型,存储的数据容量可以发生改变ArrayList集合的特点长度可以变化,只能存储引用数据类型。泛型的使......
  • 3.5 set(集合)
    set(集合)无序集合,重点就是去重和无序。(1)添加元素saddkeymember1member2...向键authors的集合中添加元素zhangsan、lisi、wangwusaddauthorszhangsanlisiwangwu(2)获取集合的所有的成员smemberskey获取键authors的集合中所有元素smembersauthors(3)获取集合的长......
  • 3.6 zset(有序集合)
    zset(有序集合)有序集合(score/value),去重并且根据score权重值来进行排序的。score从小到大排列。(1)添加成员zaddkeyscore1member1score2member2score3member3....设置榜单achievements,设置成绩和用户名作为achievements的成员127.0.0.1:6379>zaddachievements61xiao......
  • 集合的基本操作
    #集合会自己去重set1=set([1,2,3,4,5,1,2])set2=set([4,5,6,7,8])print(set1)#查询#查询具体值只能通过for循环去遍历print(1inset1)#判断是否在集合中print(1notinset1)#添加#set1.add("123")#添加单个数据##print(set1)##set1.......
  • 集合及数据结构第八节(上)————栈(Stack)、栈的模拟实现和应用
    系列文章目录集合及数据结构第八节(上)————栈(Stack)、栈的模拟实现和应用栈(Stack)、栈的模拟实现和应用(上)栈的概念栈的使用栈的模拟实现栈的应用场景栈、虚拟机栈、栈帧的概念区分文章目录系列文章目录集合及数据结构第八节(上)————栈(Stack)、栈的模拟实现和应用......
  • 集合及数据结构第七节————LinkedList的模拟实现与使用
    系列文章目录集合及数据结构第七节————LinkedList的模拟实现与使用LinkedList的模拟实现与使用无头双向链表实现什么是LinkedListLinkedList的使用LinkedList的遍历ArrayList和LinkedList的区别文章目录系列文章目录集合及数据结构第七节————LinkedList的模......
  • 8.泛型与Set集合(上篇)
    目录1.泛型2.集合类体系结构3.Set集合4.HashSet集合5.TreeSet集合1.泛型1.1泛型的介绍泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制如果我们没有给集合指定类型,默认认为所有的数据类型都是Object类型此时可以往集合添加任意的数据类型带来一个坏处:我......