技巧1:对于 f(k) = 1 ^ 2 ^ … ^ k ,可以在O(1)时间方便的求出。
这里可以看图上的规律,这个函数是以4为规律的
f
(
k
)
=
{
k
k
%
4
=
=
0
1
k
%
4
=
=
1
k
+
1
k
%
4
=
=
2
0
k
%
4
=
=
3
f(k)= \begin{cases} k& k\%4 == 0\\ 1& k\%4 == 1\\ k+1& k\%4 == 2\\ 0& k\%4 == 3\\ \end{cases}
f(k)=⎩⎪⎪⎪⎨⎪⎪⎪⎧k1k+10k%4==0k%4==1k%4==2k%4==3
技巧2:异或值除2
对于题目中的异或值,
f
(
k
)
=
k
∗
(
k
+
2
)
∗
(
k
+
4
)
∗
.
.
.
∗
(
k
+
2
n
)
f(k) = k*(k+2)*(k+4)*...*(k+2n)
f(k)=k∗(k+2)∗(k+4)∗...∗(k+2n)
这个函数其实比较烦,因为如果我们能除2,就能转换成技巧1,O(1)求解了。很棒的是,我们是可以除2的,因为除2相当于右移操作,只会影响最后一位,在考虑最后一位的情况下就可除2,加上这一位就行。
接下来考虑这道题,其实是技巧2中的函数,我们考虑除2后用技巧1处理即可。如果start是奇数并且n是奇数,那么最后一位是1,否则是0.
class Solution {
public:
int get_(int k)
{
if(k%4 == 0)return k;
else if(k%4 == 1)return 1;
else if(k%4 == 2)return k+1;
else return 0;
}
int xorOperation(int n, int start) {
int last = n&1 && start&1;
int s = start >> 1;
int val = get_(s-1)^get_(s+n-1);
return val<<1|last;
}
};