hdu 5014 Number Sequence 2014 ACM/ICPC Asia Regional Xi'an Online 数论

来源:互联网 发布:mac 10 少女前线 编辑:程序博客网 时间:2024/05/01 11:27

题目链接:hdu 5014

        给出一个从0到n的全排列数组a,求一个对应的数组使得,a[i]^b[i]的总和最大,输出总和并输出b数组

        

        要使得异或值最大,就要让每个数的1尽量加进计数中,因此对于每个数a,要找到匹配数b使得两者的异或值为两者的和

        从最高位n开始向0找每个数的匹配数,对于数a,若该数尚未匹配,则找数b使得a+b的值为2^x-1,(x为a的二进制位数),最大和即为0~n的总和的两倍

/****************************************************** * File Name:   1008.cpp * Author:      kojimai * Creater Time:2014年09月14日 星期日 13时25分56秒******************************************************/#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;#define FFF 100005int match[FFF];int val[FFF];int a[FFF];void init(){val[1]=1;for(int i = 2;i <= 17; i++){val[i]=(val[i-1]+1)*2-1;}return;}int qfind(int x){int l=1,r=17,mid;while(l<=r){mid=(l+r)/2;if(val[mid]>x){r=mid-1;}elsel=mid+1;}return l;}int main(){int n;init();while(~scanf("%d",&n)){memset(match,-1,sizeof(match));long long all=0;for(int i=0;i<=n;i++){scanf("%d",&a[i]);all+=a[i];}all*=2;int t=qfind(n);for(int i=n;i>=0;i--){if(match[i]==-1){if(i==0){match[0]=0;break;}while(i<=val[t-1])t--;match[i]=val[t]-i;match[val[t]-i]=i;}}cout<<all<<endl;//long long debug=0;for(int i=0;i<=n;i++){//debug+=match[a[i]];if(i==0)printf("%d",match[a[i]]);elseprintf(" %d",match[a[i]]);}cout<<endl;//cout<<"debug = "<<debug<<endl;}return 0;}


0 0
原创粉丝点击