题目大意
求 a⊕(a+b)⊕(a+2b)⊕...⊕(a+(n−1)b)
多组数据,T≤104, a,b,n≤109
题解
很特么简单的套路。。。
按位考虑,假设当前第 x 位,那么只用看这 n 个数中,是否有奇数个这一位为 1。
这等价于这 n 个数的第 x 位加起来是否为奇数。
因此第 x 位的答案就是 ∑i=0n−1⌊2xa+bi⌋(mod2)
于是这就是个类欧模板题。
代码
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); } }
|