給你兩個長度爲的數組
你需要把兩個數組分別按某種方式排序
然後令,你要使的字典序最小
請輸出這個數組
將這兩個數組的數分別放到一個樹裏面
並記下每個點的位置有多少串經過
然後考慮構造
兩個樹一起開始跑,從開始考慮
先考慮兩邊異或起來爲的情況,再考慮兩邊異或起來爲的
這樣跑完的點後就可以得到一個,並且一定是最優的
接下來則是技巧的問題
如果對的每個元素單獨算,即每次都重新匹配一次,儘管我將其改爲並且進行了些優化,但仍然會
考慮一遍處理所有的答案
在每個位置都先考慮異或起來爲,再考慮異或起來爲的情況
然後每次將改點經過的串的個數減
這樣就可以過了
50分代碼
/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年09月16日 星期一 09時45分46秒
*******************************/
#include <cstdio>
#include <fstream>
#include <algorithm>
using namespace std;
const int len = 30;
const int maxn = 3000006;
//{{{cin
struct IO{
template<typename T>
IO & operator>>(T&res){
res=0;
bool flag=false;
char ch;
while((ch=getchar())>'9'||ch<'0') flag|=ch=='-';
while(ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
if (flag) res=~res+1;
return *this;
}
}cin;
//}}}
int n,a,b,h,t,k,cnt;
int mi[len+1],res[maxn];
int q[3][maxn];//q[0] -> 哪一位 q[1] -> na q[2] -> nb
struct Trie{
int tot=1;
int num[maxn];
int ch[maxn][2];
//{{{insert
void insert (int s)
{
int now=1;
for (int i=len;i>=0;--i){
bool to=s&mi[i];
if (!ch[now][to]) ch[now][to]=++tot;
now=ch[now][to];
++num[now];
}
}
//}}}
}A,B;
//{{{dfs
void dfs(int x,int y,int S,int k)
{
if(x) --A.num[x],--B.num[y];
if(k<0) { res[++cnt]=S;return;}
while(A.num[A.ch[x][0]]&&B.num[B.ch[y][0]]) dfs(A.ch[x][0],B.ch[y][0],S,k-1);
while(A.num[A.ch[x][1]]&&B.num[B.ch[y][1]]) dfs(A.ch[x][1],B.ch[y][1],S,k-1);
while(A.num[A.ch[x][0]]&&B.num[B.ch[y][1]]) dfs(A.ch[x][0],B.ch[y][1],S|mi[k],k-1);
while(A.num[A.ch[x][1]]&&B.num[B.ch[y][0]]) dfs(A.ch[x][1],B.ch[y][0],S|mi[k],k-1);
}
//}}}
int main()
{
mi[0]=1;
for (int i=1;i<=len;++i) mi[i]=mi[i-1]<<1;
cin>>n;
for (int i=1;i<=n;++i) cin>>a,A.insert(a);
for (int i=1;i<=n;++i) cin>>b,B.insert(b);
dfs(1,1,0,30);
sort(res+1,res+n+1);
for (int i=1;i<=n;++i) printf("%d ",res[i]);
return 0;
}
100分代碼
/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年09月16日 星期一 09時45分46秒
*******************************/
#include <cstdio>
#include <fstream>
#include <algorithm>
using namespace std;
const int len = 30;
const int maxn = 3000006;
//{{{cin
struct IO{
template<typename T>
IO & operator>>(T&res){
res=0;
bool flag=false;
char ch;
while((ch=getchar())>'9'||ch<'0') flag|=ch=='-';
while(ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch^'0'),ch=getchar();
if (flag) res=~res+1;
return *this;
}
}cin;
//}}}
int n,a,b,h,t,k,cnt;
int mi[len+1],res[maxn];
int q[3][maxn];//q[0] -> 哪一位 q[1] -> na q[2] -> nb
struct Trie{
int tot=1;
int num[maxn];
int ch[maxn][2];
//{{{insert
void insert (int s)
{
int now=1;
for (int i=len;i>=0;--i){
bool to=s&mi[i];
if (!ch[now][to]) ch[now][to]=++tot;
now=ch[now][to];
++num[now];
}
}
//}}}
}A,B;
//{{{dfs
void dfs(int x,int y,int S,int k)
{
if(x) --A.num[x],--B.num[y];
if(k<0) { res[++cnt]=S;return;}
while(A.num[A.ch[x][0]]&&B.num[B.ch[y][0]]) dfs(A.ch[x][0],B.ch[y][0],S,k-1);
while(A.num[A.ch[x][1]]&&B.num[B.ch[y][1]]) dfs(A.ch[x][1],B.ch[y][1],S,k-1);
while(A.num[A.ch[x][0]]&&B.num[B.ch[y][1]]) dfs(A.ch[x][0],B.ch[y][1],S|mi[k],k-1);
while(A.num[A.ch[x][1]]&&B.num[B.ch[y][0]]) dfs(A.ch[x][1],B.ch[y][0],S|mi[k],k-1);
}
//}}}
int main()
{
mi[0]=1;
for (int i=1;i<=len;++i) mi[i]=mi[i-1]<<1;
cin>>n;
for (int i=1;i<=n;++i) cin>>a,A.insert(a);
for (int i=1;i<=n;++i) cin>>b,B.insert(b);
dfs(1,1,0,30);
sort(res+1,res+n+1);
for (int i=1;i<=n;++i) printf("%d ",res[i]);
return 0;
}
如有哪裏講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧