不斷的異或就可以了, 用了一個等差數列連續異或的模板
#include <cstdio>
typedef __int64 LL;
#include <iostream>
using namespace std;
LL Get(LL a,LL b,LL c,LL n) {
LL res=0;
res+=(b/c)*n;b%=c;
res+=(a/c)*n*(n-1)/2;a%=c;
if (a*n+b<c) return res;
else return res+Get(c,(a*n+b)%c,a,(a*n+b)/c);
}
LL GetYiHuo(LL x, LL y, LL z) //以x開始, y爲結束, z爲等差 連續異或
{
{
LL k,ans,Sum,P,i;
ans=0;
k=(y-x)/z+1;P=1;
for (i=1;i<=35;i++,P<<=1) {
Sum=Get(z,x,P,k);
if (Sum & 1) ans+=P;
}
return ans;
}
}
LL a[20003], b[20003], c[20003];
int main()
{
int N;
while(scanf("%d", &N) != EOF)
{
LL x, y, z;
LL tmp = 0;
for(int i = 0; i < N; i++)
{
scanf("%I64d %I64d %I64d", &x, &y, &z);
a[i] = x, b[i] = y, c[i] = z;
LL tt = GetYiHuo(x, y, z);
tmp ^= tt;
}
if(tmp == 0)
{
puts("DC Qiang is unhappy.");
continue;
}
int count = 0;
for(int i = 0; i < N; i++)
{
if(tmp >= a[i] && (tmp - a[i]) % c[i] == 0 && tmp <= b[i])
count++;
}
printf("%I64d %I64d\n", tmp, count);
}
return 0;
}