Codeforces Round #177 (Div. 2)---E. Polo the Penguin and XOR operation

题意:让你构造一个序列,使得序列异或和最大,序列为n 的全排列 ,序列和计算方式为 SUM = a[1] ^ 0 + a[2] ^ 1 + a[3] ^ 2 + .......a[n] ^ n

感想 :之前没做过有关位运算的题,对这一块很陌生,两个数异或以后,如果二进制每一位都为1,那么一定最大,找规律发现当n为偶数时 除开0以外,其他的都是成对出现

当n为奇数时 都是成对出现 例如n=4, 0 1 2 3 4 分别对应0 2 1 4 3 ;n=5时 0 1 2 3 4 5 分别对应1 0 5 4 3 2 自己可以在草稿纸上模拟下;

ac代码:

#include<iostream>
#include<cstring>
#include<cstdio>
typedef __int64 ll;
using namespace std;
ll result[1000010];
ll n;
int main()
{
      while(scanf("%I64d",&n)!=EOF)
     {
           ll k=1;
           while(k<=n)
           k*=2;
           k--;
           memset(result,-1,sizeof(result));
           for(int i=n;i>=0;i--)//反着找 不用分奇数和偶数讨论
          {
                   if(result[i]!=-1)//已经匹配了  继续下一个数
                      continue;
                   else
                  {
                          while((k^i)>n||result[k^i]!=-1)
                                   k/=2;
                          result[k^i]=i;
                          result[i]=k^i;//例如上面第二个例子中   result[2]=5;result[5]=2;
                   }
            }//注  w^q^q=w;上面的k即为下面j^result[j]的结果
            ll sum=0;
            for(int j=0;j<=n;j++)
            sum+=j^result[j];
            printf("%I64d\n",sum);
            for(int q=0;q<n;q++)
            printf("%I64d ",result[q]);
            printf("%I64d\n",result[n]);
      }
      return 0;
}

//不好的话直接提出来 ,本人水平太低了 望大家指教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值