牛客编程巅峰赛S2第10场 XOR和

题意: 给定 n n n,问 ∑ i = 1 n ( i ⊕ ( i − 1 ) ) \sum_{i=1}^n(i\oplus(i-1)) i=1n(i(i1))
数据范围: 1 ≤ n ≤ 1 0 9 1\leq n\leq 10^9 1n109

题解:
考虑一个数 x x x和其减 1 1 1后的 x − 1 x-1 x1
对于偶数: x = 100100 , x − 1 = 100011 , x ⊕ ( x − 1 ) = 000111 x=100100,x-1=100011, x\oplus(x-1)=000111 x=100100,x1=100011,x(x1)=000111
对于奇数: x = 100011 , x − 1 = 100010 , x ⊕ ( x − 1 ) = 000001 x=100011,x-1=100010,x\oplus(x-1)=000001 x=100011,x1=100010,x(x1)=000001
可以发现两者的都为: x x x的二进制最低位 1 1 1往低位都补满的值,但是这样仍然不够。
考虑二进制中的每一位对答案的贡献次数:
对于二进制第 i i i位,则该位被补到使得该位对答案产生贡献时,一定是所有 x x x最低位 1 1 1不比第 i i i位低的时候。那么可以考虑到二进制第 i i i位一次的贡献为 2 i 2^i 2i,故若 x x x 2 i 2^i 2i的倍数,则 x x x会对答案产生一个 2 i 2^i 2i贡献。那么只需要考虑所有的 2 2 2的幂即可。

代码:

typedef long long ll;
class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param n int整型 
     * @return long长整型
     */
    long long Sum(int n) {
    
    
        // write code here
        ll now = 1, res = 0;
	    while(now <= n) {
    
    
            res += n / now * now;
            now <<= 1;
	    }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43900869/article/details/111407177
今日推荐