因为异或运算看成可以每一位单独单独做加法运算,也就是求
∑i=0312i⎛⎝⎜∑j=0⌊(y−x)z⌋⌊zj+x2i⌋)%2⎞⎠⎟
不妨写成更一般的形式,求
∑x=0n−1⌊ax+bc⌋
首先把 a 和
⌊ac⌋n(n−1)2+⌊bc⌋n+∑x=0n−1⌊a%c∗x+b%cc⌋
对于后面这个东西,不妨记 f(x)=a%c∗x+b%cc 。以点 (n,⌊f(n)⌋) 为原点, y 轴负方向为
斜率就是 ca%c 。定义域就是 ⌊f(n)⌋ 。截距需要求出 f(w)=⌊f(n)⌋ 的 w ,解方程得到
于是我们惊喜地发现,斜率和截距的分母一样,因此变成了和原来问题形式相同的问题。而且原来的整数对 (a,c) 变成了 (c,a%c) 。根据辗转相除,这样肯定能算完。于是问题就解决了,复杂度是 O(log2n) 。
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
LL solve(LL n,LL a,LL b,LL c)
{
if (c==0) return 0;
return a/c*n*(n-1)/2+b/c*n+solve((a%c*n+b%c)/c,c,(a*n+b)%c,a%c)&1;
}
int main()
{
LL x,y,z,n,ans;
while (scanf("%lld%lld%lld",&x,&y,&z)==3)
{
ans=0;
n=(y-x)/z;
for (int i=0;i<32;i++) ans|=solve(n+1,z,x,1LL<<i)<<i;
printf("%lld\n",ans);
}
}