【JZOJ5149】超级绵羊异或 题解

题目大意

  求 $a\oplus(a+b)\oplus(a+2b)\oplus…\oplus(a+(n-1)b)$
  多组数据,$T \leq 10^4$, $a,b,n \leq 10^9$

题解

  很特么简单的套路。。。

  按位考虑,假设当前第 $x$ 位,那么只用看这 $n$ 个数中,是否有奇数个这一位为 $1$。
  这等价于这 $n$ 个数的第 $x$ 位加起来是否为奇数。
  因此第 $x$ 位的答案就是 $\sum_{i=0}^{n-1} \lfloor \frac{a+bi}{2^x} \rfloor \pmod{2}$

  于是这就是个类欧模板题。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<cstdio>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long LL;

const LL mo=2;

int n,a,b;

LL f(LL a,LL b,LL c,LL n)
{
if (!a) return (n+1)*(b/c)%mo;
if (a>=c || b>=c)
{
LL sqr=(n&1) ?(n+1)/2*n :n/2*(n+1) ;
return (f(a%c,b%c,c,n)+(a/c)*sqr+(n+1)*(b/c))%mo;
} else
{
LL m=(a*n+b)/c;
return (m*n-f(c,c-b-1,a,m-1)+mo)%mo;
}
}

int T;
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%d %d %d",&n,&a,&b);

LL ans=0;
fd(x,62,0)
{
LL c=1ll<<x;
if (f(b,a,c,n-1)) ans+=c;
}

printf("%lld\n",ans);
}
}