Solution Of 读取信息J(dqxxj)

return

这是我的原创题

注:\(\oplus\) 表示异或 或者 异或和。\(\land\) 表示 逻辑与 ,\(\lor\) 表示 逻辑或

首先说明集合上的异或运算——对称差:对于集合 \(A\)\(B\)\(A \oplus B\)\(A\)\(B\) 的对称差)\(= \bigg\{\ x\ \bigg|\ \Big((x \in A) \land (x \notin B)\Big) \lor \Big((x \notin A) \land (x \in B)\Big) \bigg\}\)

记序列为 \(U\),定义集合求值运算 \([?]\),即 \([A]={\bigoplus}_{i \in A}{\ U_i}\) ,易证明:\([A \oplus B]=[A] \oplus [B]\)

回到题目,先假设一定存在序列 \(U\) 满足所有描述,每次问题答案唯一确定

于是对于某个询问集合 \(Q\),只需找出若干个描述集合 \(P_i\),使 \(Q={\bigoplus}{P_i}\),则询问答案\([Q]\)可用上式计算(\([Q]=[{\bigoplus}{P_i}]={\bigoplus}{[P_i]}\)

如果无法找到这样的若干描述集合,则无法唯一确定询问答案

如果对于某个描述集合 \(P_0\),能找到若干描述集合 \(P_i\),使 \(P_0={\bigoplus}{P_i}\),且 \([P_0] \neq {\bigoplus}{[P_i]}\),则不存在序列 \(U\) 满足所有描述

对于一个集合 \(P\),如何快速找到若干若干集合 \(P_i\) 使 \(P={\bigoplus}{P_i}\)

可以把一个位置集合转化为一个 \(n\)\(01\) 串二进制,第 \(i\)\(1/0\) 表示位置 \(i\) 是否在该集合中,那么每个集合 \(P\) 就唯一映射一个整数 \(t\)

于是问题转化为,对于一个集合 \(P\) 的映射 \(t\),如何快速找到若干集合 \(P_i\) 的映射 \(t_i\) 使 \(t={\bigoplus}{t_i}\)

显然可以用线性基

但题目不仅判定,还要求求值,怎么办?

标题中有提示:$dqxxj \rightarrow $ 带权线性基

具体的:

#define N 160
class LBwK/*linear base with key*/{
	private:
	struct node{
		bitset<N>bit;
		//线性基中某一维度的基底 
		int filled;
		//该维度基底是否被填充 
		int key;
		//该维度基底的值(或者说 权) 
	}base[N];
	public:
	inline int find(bitset<N>bit){
		int sum_key=0;
		for(register int i=0;i<N;++i)
		if(bit.test(i)){
			if(base[i].filled){
				bit^=base[i].bit;
				sum_key^=base[i].key;
			}
			else return -1;
			//找不到异或和为目标的基底组合 
		}
		return sum_key;
		//找到异或和为目标的基底组合,并返回基底组合的值的异或和 
	}
	inline bool insert(bitset<N>bit,int key=0){
		for(register int i=0;i<N;++i)
		if(bit.test(i)){
			if(base[i].filled){
				bit^=base[i].bit;
				key^=base[i].key;
			}
			else{
				base[i].bit^=bit;
				base[i].key^=key;
				base[i].filled=1;
				return true;
				//插入线性基成功 
			}
		}
		return !key;
		//插入失败,集合可以被现有基底表示,返回给出集合的值是否与现有值矛盾 
	}
}base;
#undef N

总复杂度 \(O\Big(\frac{n^2}{w} (m+q)\Big)\)

posted @ 2021-10-21 22:11  沼中蒻杨  阅读(79)  评论(0)    收藏  举报