題目連結
http://acm.hdu.edu.cn/showproblem.php?pid=5536
題意
給定一個數列,從數列中取出坐标不同的三個數,其中兩個求和,再和另外一個數異或,求異或值的最大值。
思路
和hdu4825相似,隻不過因為要三個坐标不同,如果直接去字典樹上比對的話不能判斷坐标,是以再比對之前先将s[i]和s[j]删除,比對完之後再添加上。
代碼
#define push_back pb
#define make_pair mk
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<string.h>
#include<set>
#include<queue>
#include<stack>
#include<functional>
using std::pair;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
const double PI=acos(-);
const int maxn = + ;
const int maxm = + ;
const int INF = ;
const int mod =+;
const ll inf =;
using namespace std;
int n;
struct Trie
{
int son[maxn*][],cnt,sum[maxn*],end[maxn*];
void init()
{
memset(son,,sizeof(son));
cnt=;
memset(sum,,sizeof(sum));
memset(end,,sizeof(end));
}
void insert(int n)
{
int rt=;
for(int i=;i>=;i--)
{
int t=(n>>i)&;
if(son[rt][t]==) son[rt][t]=++cnt;
rt=son[rt][t];
sum[rt]++;
}
end[rt]=;
}
void del(int n)
{
int rt=;
for(int i=;i>=;i--)
{
int t=(n>>i)&;
rt=son[rt][t];
sum[rt]--;
}
}
int query(int n)
{
int rt=;
int ans=;
for(int i=;i>=;i--)
{
int t=((n>>i)&)^;
if(son[rt][t]==||sum[son[rt][t]]==) t^=;
ans|=(t<<i);
rt=son[rt][t];
}
return ans;
}
}trie;
int main()
{
int t;
cin>>t;
while(t--)
{
trie.init();
scanf("%d",&n);
int a[];
for(int i=;i<n;i++)
{
scanf("%d",&a[i]);
trie.insert(a[i]);
}
int ans=;
for(int i=;i<n-;i++)
{
for(int j=i+;j<n;j++)
{
trie.del(a[i]);
trie.del(a[j]);
int res=trie.query(a[i]+a[j]);
res^=(a[i]+a[j]);
ans=max(ans,res);
trie.insert(a[i]);
trie.insert(a[j]);
}
}
printf("%d\n",ans);
}
}
當然這個題因為9s的時限,用暴力也不會逾時,時間為4s,而字典樹為3.8s,字典樹對這個題并沒有太大的優勢。
#define push_back pb
#define make_pair mk
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<string.h>
#include<set>
#include<queue>
#include<stack>
#include<functional>
using std::pair;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
const double PI=acos(-);
const int maxn = + ;
const int maxm = + ;
const int INF = ;
const int mod =+;
const ll inf =;
using namespace std;
int n;
int a[];
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d",&a[i]);
}
int res=;
for(int i=;i<n-;i++)
{
for(int j=i+;j<n-;j++)
{
for(int k=j+;k<n;k++)
{
res=max(res,(a[i]+a[j])^a[k]);
res=max(res,(a[i]+a[k])^a[j]);
res=max(res,(a[k]+a[j])^a[i]);
}
}
}
printf("%d\n",res);
}
}