poj3495 Bitwise XOR of Arithmetic Progression

125 篇文章 0 订阅

因为异或运算看成可以每一位单独单独做加法运算,也就是求

i=0312ij=0(yx)zzj+x2i)%2

不妨写成更一般的形式,求
x=0n1ax+bc

首先把 a b整除的部分提出来,得到
acn(n1)2+bcn+x=0n1a%cx+b%cc

对于后面这个东西,不妨记 f(x)=a%cx+b%cc 。以点 (n,f(n)) 为原点, y 轴负方向为x轴正方向, x 轴负方向为y轴正方向建立新的直角坐标系。考虑到 yf(n) x<0 的区域都没有整点,可以把这个东西看成新坐标系下原直线的整点个数。因此需要表示出新坐标系下原直线的斜率、截距和定义域。
斜率就是 ca%c 。定义域就是 f(n) 。截距需要求出 f(w)=f(n) w ,解方程得到w=nn%cb%ca%c,因此截距是 (an+b)a%c
于是我们惊喜地发现,斜率和截距的分母一样,因此变成了和原来问题形式相同的问题。而且原来的整数对 (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);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值