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 */