poj3495 Bitwise XOR of Arithmetic Progression

来源:互联网 发布:天刀阿暖捏脸数据 编辑:程序博客网 时间:2024/06/05 10:18

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

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

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

首先把ab整除的部分提出来,得到
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 longLL 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 0
原创粉丝点击