不断的异或就可以了, 用了一个等差数列连续异或的模板
#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; }