codeforces 959E Mahmoud and Ehab and the xor-MST

E. Mahmoud and Ehab and the xor-MST

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.

Input

The only line contains an integer n (2 ≤ n ≤ 1012), the number of vertices in the graph.

Output

The only line contains an integer x, the weight of the graph's minimum spanning tree.

Example
input
Copy
4
output
Copy
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
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值