题意:给出范围N,给出0-N的一个排列a。让你求出另外一个排列b,使 t = a1 ^ b1 + a2 ^ b2 + ...+an ^ bn(^表示异或)最大。并求出最大的t。
思路:首先,我们要注意到的是,一定存在解,且解不唯一。同时,因为是异或操作,要想得到最大值,我们必须让ai,bi对应的二进制表示,0和1错开,这样才不会使值减少。
这样,我们要构造出错开的0和1的二进制表达即可。
代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int a[100100];
int ans[100100];
int n;
int main()
{
//freopen("input.txt","r",stdin);
while (scanf("%d",&n)!=EOF){
for (int i=0;i<=n;i++)
scanf("%d",&a[i]);
memset(ans,-1,sizeof(ans));
int x,maxnum,xornum;
long long maxans=0;
for (int i=n; i >= 0; i--)
if (ans[i]==-1){
x=log2(i)+1;
maxnum=(1<<x)-1;
xornum=maxnum^i;
if (ans[xornum]==-1){
ans[i]=xornum;
ans[xornum]=i;
maxans += 2 * maxnum;
}
}
printf("%I64d\n",maxans);
for (int i=0; i <= n; i++)
printf("%d%c",ans[a[i]], i ==n?'\n':' ');
}
return 0;
}
本文介绍了一种解决特定问题的方法:给定一个0至N的整数排列,通过构造另一个排列来最大化异或和。文章详细解释了如何确保两个排列的二进制位上的0和1尽可能错开,从而实现异或和的最大化。

2093

被折叠的 条评论
为什么被折叠?



