超级绵羊异或

题目大意

求 (a) xor (a + b) xor (a + b * 2) xor … xor (a + b * (n - 1))。

题解

考虑计算答案第k位是否为1。
对于一个a+bi,判断它第k位是否为1。
那么就是看 a+bi2k 是否是奇数。
然后发现我们可以写出这样一个式子,判断它的奇偶性。
n1i=0a+bi2k
这是经典的类欧几里得算法,在模2意义下进行即可。

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxd=62,mo=2;
int i,j,k,l,t,n,m,ca,a,b;
ll ans,x,last;
ll likegcd(ll a,ll b,ll c,ll n){
    if (!a) return 0;
    if (a>=c||b>=c){
        ll t=likegcd(a%c,b%c,c,n);
        ll l=(a/c)*(n*(n+1)/2%mo)%mo+(b/c)*(n+1)%mo;
        (l+=t)%=mo;
        return l;
    }
    ll m=(a*n+b)/c;
    ll t=likegcd(c,c-b-1,a,m-1);
    t=(n*m%mo-t)%mo;
    (t+=mo)%=mo;
    return t;
}
int main(){
    freopen("shxor.in","r",stdin);freopen("shxor.out","w",stdout);
    scanf("%d",&ca);
    while (ca--){
        scanf("%d%d%d",&n,&a,&b);
        if (b==0){
            if (n%2==1) printf("%d\n",a);else printf("0\n");
            continue;
        }
        ans=0;
        x=1;
        fo(k,0,maxd){
            if (likegcd(b,a,x,n-1)) ans^=x;
            x*=2;
        }
        printf("%lld\n",ans);
        /*if (ans==0&&last==174374687) printf("%d %d %d\n",n,a,b); last=ans;*/
    }
}

你可能感兴趣的:(超级绵羊异或)