題目:給出 n 個數 a 1 ..a n ,求 a i xor a j , (i不等於j) 的最大值
• 對於 30% 的數據,n ≤ 1000。
• 對於另外 20% 的數據,數據保證最後的 ans 一定是 2^k − 1。
• 對於 70% 的數據,n ≤ 10 ^5 ,0 ≤ a i ≤ 10 ^7 。
• 對於 100% 的數據,n ≤ 10 ^5 ,0 ≤ a i ≤ 10 ^16 。
第一次打字典樹。。。
把每個數轉化二進制建樹,樹的第i層就是二進制的第i位, 每個節點有兩個孩子,分別表示該位上0與1是否存在。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> long long n,i,j,a[100005],ans,b[5600005][2],u,v,s,t; int main() { scanf("%lld",&n); ans=0; for (i=1;i<=n;i++) { scanf("%lld",&a[i]); for (j=55;j>=0;j--) //10^16大概55位 { v=(a[i]>>j)&1; if (b[u][v]==0) b[u][v]=++t; //若當前位還不存在則新延伸一個節點,新節點編號爲t u=b[u][v]; //並且走到新的節點 } u=0; } for (i=1;i<=n;i++) //每個數都找一遍 { s=0;u=0; for (j=55;j>=0;j--) { v=(a[i]>>j)&1; if (!b[u][v^1]) u=b[u][v]; //若與當前位相反的節點不存在,只能走走當前位 else { u=b[u][v^1]; //否則走到與當前位相反的節點 s|=(1ll<<j); //此時第j位上值爲1 計入答案 } } ans=std::max(ans,s); } printf("%lld",ans); }