Ehab is interested in the bitwise-xor operation and the special graphs. Mahmoud gave him a problem that combines both. He has a complete graph consisting of n vertices numbered from 0 to n - 1. For all 0 ≤ u < v < n, vertex u and vertex v are connected with an undirected edge that has weight (where is the bitwise-xor operation). Can you find the weight of the minimum spanning tree of that graph?
You can read about complete graphs in https://en.wikipedia.org/wiki/Complete_graph
You can read about the minimum spanning tree in https://en.wikipedia.org/wiki/Minimum_spanning_tree
The weight of the minimum spanning tree is the sum of the weights on the edges included in it.
The only line contains an integer n (2 ≤ n ≤ 1012), the number of vertices in the graph.
The only line contains an integer x, the weight of the graph's minimum spanning tree.
4
4
发现找规律 很重要,
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const int maxn = 100000;
ll n,ans;
/*
发现奇数 n 就与前面的那个偶数 n-1 异或是最好的情况( n^(n-1) == 1)
偶数 n 就与 n^(n^(1<<L)) / L为n二进制中的最低为1的位 / 这个数 异或 取最好的情况 ( n ^ (n^(1<<L)) == (1<<L) )
所以对整数 N
奇数贡献 N/2+N%2
偶数贡献 枚举最低为1的位 求贡献
比如 n = 1001001000
枚举最低为1的位:
n = 1001001000
10
100
1000
....
ans =:
小于等于 1000000000 的偶数贡献
小于等于 1000000 的偶数贡献
小于等于 1000 的偶数贡献
*/
int main()
{
while(~scanf("%lld",&n))
{
n--;
int l = 0;
for(int i=0; i<50; i++) if((1ll<<i)&n) l = i;
ans = n/2+n%2;//奇数的贡献
int f = l;
for(; f>0; f--)//小于等于n的偶数贡献,枚举偶数为1的最低
{
if((1ll<<f)&n)//为1的位
{
int k = f;
ans+=(1ll<<f);//等于 (1<<k)的贡献
for(int i=1; i<k; i++)// 小于 (1<<k)的贡献
{
ans+=(1ll<<i)*(1ll<<(k-1-i));//此位贡献 (1<<i) 有(k-1-i)个这样的偶数情况
}
}
}
printf("%lld\n",ans);
}
return 0;
}
/*
1025
6144
158
653
99
371
98
369
1001
5060
11111
79227
123
439
321
1536
2000
11104
56
172
*/