题面 & 题解
T1
题面让我们求一个排列 \(p\), 使得 \(a_i \oplus b_{p_i} = x\), 其中每一个 \(x\) 均相等, 最后升序输出每一个 \(x\).
不难发现, \(x\) 只可能是 \(a_1 \oplus b_i\). (当然, \(a_1\) 可以是序列 \(a\) 中的其他数)
故我们可以枚举每一个可能的 \(x\) (即 \(a_1 \oplus b_i\)), 然后判断是否合法即可.
时间复杂度 \(\mathcal{O}(n^2 \log n)\) (我用的 \(multiset\), 用哈希表可以做到 \(\mathcal{O}(n^2)\)).
#include "iostream"
#include "algorithm"
#include "set"using namespace std;const int N=2e3+10;int n;
int a[N],b[N];int main(){#ifdef FILE_IOfreopen("f.in","r",stdin);freopen("f.out","w",stdout);
#endifscanf("%d",&n);for (int i=1;i<=n;++i) scanf("%d",a+i);for (int i=1;i<=n;++i) scanf("%d",b+i);if (n<=10){int p[11],x;bool f=1;set<int> ans;for (int i=1;i<=n;++i) p[i]=i;x=a[1]^b[p[1]];for (int i=2;i<=n;++i)if (x!=(a[i]^b[p[i]])){f=0;break;}if (f) ans.insert(x);while (next_permutation(p+1,p+n+1)){f=1,x=a[1]^b[p[1]];for (int i=2;i<=n;++i){if ((a[i]^b[p[i]])!=x){f=0;break;}}if (f) ans.insert(x);}printf("%d\n",ans.size());for (int x:ans) printf("%d\n",x);}else{set<int> ans;multiset<int> s;for (int i=1;i<=n;++i){s.clear();for (int j=1;j<=n;++j) if (j!=i) s.insert(b[j]);int x=a[1]^b[i];bool f=1;for (int j=2;j<=n;++j){if (s.find((x^a[j]))==s.end()){f=0;break;}s.erase((x^a[j]));}if (f) ans.insert(x);}printf("%d\n",ans.size());for (int x:ans) printf("%d\n",x);}return 0;
}