【CodeForces - 288C】Polo the Penguin and XOR operation (思維、異或運算)
Little penguin Polo likes permutations. But most of all he likes permutations of integers from 0 to n, inclusive.
For permutation p = p0, p1, ..., pn, Polo has defined its beauty — number .
Expression means applying the operation of bitwise excluding "OR" to numbers x
Help him find among all permutations of integers from 0 to n the permutation with the maximum beauty.
Input
The single line contains a positive integer n (1 ≤ n ≤ 106).
Output
In the first line print integer m the maximum possible beauty. In the second line print any permutation of integers from 0 to n with the beauty equal to m.
If there are several suitable permutations, you are allowed to print any of them.
Examples
Input
4
Output
20 0 2 1 4 3
題意:
給0~n,n+1個數讓你找出一種排列,使得第i個位置上的數字與i做異或運算,然後所有運算結果加和,求使得加和最大排列。
思路:
首先,我們應該知道兩個數做異或運算是相同為1,不同為0,即兩個數都看成二進位制,每一位都做運算,這一位上兩個都是1或都是0,那麼運算結果是0,否則為1。
如果想要最後的加和最大,那麼儘量 就不要讓兩個數的二進位制有重合的1,,因為如果有重合的1,那麼異或完之後的結果一定會比兩個數直接加和要小,如果沒有衝突的1,那麼兩個數異或完後的結果應該等於兩個數的加和。因此我們可以把二進位制每一位都是1的數找出來,打個表。然後從後往前找,先找最後一個數n,從表中找到大於等於他的第一個數,然後兩個數的差,就是最好的和n匹配的數,然後以這兩個數為端點,同時向中間縮排,每一個數一定都是符合條件的最大的(可以自己寫一下看看),接下來把最大的端點換成上次迴圈的起點的前一個數,重複迴圈,直到起點為0為止。
這道題目應該注意的是,最後的加和會很大所以應該開longlong,其次打表時,要注意範圍,看看打的長度夠不夠。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<set>
#include<iostream>
#include<map>
#include<stack>
#include<cmath>
#include<algorithm>
#define ll long long
#define mod 1000000007
#define eps 1e-8
using namespace std;
int num[1010101];
int main()
{
int n,k;
ll sum=0;//加和很大記得開longlong
scanf("%d",&n);
int one[100]={0};
one[1]=1;
for(int i=2;i<=24;i++)
{
one[i]=(one[i-1]<<1)+1;//打表後,要看看是不是比給的範圍大,不要打小了
}
int ne=n;
while(1)
{
int tt=*lower_bound(one,one+23,ne);
int ff=tt-ne;
for(int st=tt-ne,ed=ne;st<ed;ed--,st++)
{
sum+=(st^ed)*2;
num[st]=ed;
num[ed]=st;
}
ne=tt-ne-1;
if(ff==0||ne<0)
break;
}
printf("%lld\n",sum);
printf("%d",num[0]);
for(int i=1;i<=n;i++)
{
printf(" %d",num[i]);
}
putchar('\n');
}