Solution Of 读取信息J(dqxxj)
这是我的原创题
注:\(\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)\)
本文来自博客园,作者:蒻杨,转载请注明原文链接:https://www.cnblogs.com/weed-yang/

浙公网安备 33010602011771号