hdu5014---数列异或
程序员文章站
2022-06-27 19:34:54
...
解题思路:一开始以为每两两异或的最大值取决于初始数列的最大值的二进制位对应的最大数,但是经验证这是错误的,这样不光会出现重复的数,而且还会得出超过n的数。。。。
正解是:a[i]^b[i]=x,x应该为a[i]的二进制位数表示的最大数,那么b[i]=a[i]^x;这样不会出现超过n的数,并且不会出现相同的b[i];
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
int a[100010];
int ans[100010],temp;
bool flag[100010];
int main(){
int n;
while(~scanf("%d",&n)){
for(int i=0;i<=n;i++){
scanf("%d",&a[i]);
}
ll sum=0;
memset(flag,false,sizeof(flag));
flag[0]=true;
ans[0]=0;
for(int i=n;i>0;i--){
if(flag[i])continue;//已经配对
int len=log2(i)+1;//计算i的二进制位数
temp=(((1<<len)-1)^i);//与i相配的数
//配对
ans[temp]=i;
ans[i]=temp;
//加上这个异或最大值
sum+=((1<<len)-1);
//标记已经配对的
flag[i]=flag[ans[i]]=true;
}
//sum要乘2,因为flag成对标记
printf("%lld\n",sum*2);
for(int i=0;i<n;i++){
printf("%d ",ans[a[i]]);//与a[i]的配对的数
}
printf("%d\n",ans[a[n]]);
}
return 0;
}
// /\ | / |**、
// / \ | / | \
// / \ |/ | / _____ ____ | /
// /------\ |\ |__/ / \ \ /\ / / \ | /
// / \ | \ | / \ \ / \ / /______\ |/
// / \ | \ | \ / \ / \ / \ |
// / \ | \ | \_____/ \/ \/ \_____ |
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
// _ooOoo_
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// ____/`---'\____
// .' \| |// `.
// / \||| : |||// \
// / _||||| -:- |||||- \
// | | \\ - /// | |
// | \_| ''\---/'' | |
// \ .-\__ `-` ___/-. /
// ___`. .' /--.--\ `. . __
// ."" '< `.___\_<|>_/___.' >'"".
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
// \ \ `-. \_ __\ /__ _/ .-` / /
// ======`-.____`-.___\_____/___.-`____.-'======
// `=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
上一篇: 权限控制的解决方式(科普向)
下一篇: Ehcache入门经典:第一篇