标签:次数 display mat 个数 简单的 math code floor sum
又是一个不眠之夜。
求:
对于\(f_i\)的第\(j\)位,它的值只与该位1出现次数有关。
而第\(j\)位1的出现又是呈周期性分布的。
我们考虑\(f_i=0 \bigoplus 1 \bigoplus 2 \bigoplus 3 \bigoplus...\bigoplus (i-1) \bigoplus i\)。
注意这里多加了一个0。
那么,在上式的各数中,第1位的变化为01010101
而第2位为00110011
第3位为00001111
以此类推。
所以我们可以发现,第\(j\)位的值的出现是连续的,且每连续一组的相同值的个数为\(2^{j-1}\),这恰好是第\(j\)位的位权!
而对于数字的总个数,我们可以用\(x=i+1\)来表示。
分析第\(j\)位的值\((j \ge 2)\):
则第\(j\)位的出现的整组共有\(t=\lfloor{{x}\over{2^{j-1}}}\rfloor\)个,其中奇数组为0,偶数组为1,且其中出现数字1的总个数必定为偶数。
若\(t\)为奇数,说明剩余的不完整组的值为1,同时若\(x\)也为奇数,说明\(f_i\)的第\(j\)位为1;否则\(f_i\)的第\(j\)位为0。
由此,我们可以得到第\(j\)位的值\((j \ge 2)\)。
对于第1位,它出现的组共有\(x\)个,其中值为1的有\(\lfloor{{x}\over{2}}\rfloor\)个,故\(f_i\)的第1位等于\(x\)的第2位。
综上可以在\(O(logn)\)时间复杂度内求解。
其实就是对\(O(logn)\)的算法作了一个小的总结。
分析第\(j\)位的值\((j \ge 2)\):
我们知道,当且仅当\(t = \lfloor{{x}\over{2^{j-1}}}\rfloor\)为奇数,同时\(x\)也为奇数时,第\(j\)位才为1;否则第\(j\)位为0。
体现在\(x\)这个数本身上,就是当\(x\)第1位为1时,\(f_i\)的第2位及以上与\(x\)的相同。
而当\(x\)第1位为0时,\(f_i\)的第2位及以上都为0。
然后第1位的特判很好处理,就是\(f_i\)的第1位等于\(x\)的第2位。
由此可以在\(O(1)\)时间复杂度内求解。
闲来无事写个代码(因为太菜所以不会更简单的写法)
int xorsum(int x)
{
++x;
return ( (x&1) ? (x&(INT_MAX-1)) : 0 ) | ( (x&2) ? 1 : 0 );
}
标签:次数 display mat 个数 简单的 math code floor sum
原文地址:https://www.cnblogs.com/-SingerCoder/p/13171117.html