题目意思是对于区间[a,b],和[c,d]内的任意一对数,求他们的异或之和、
开始不知道算法怎么写,看了题解,要先求出每个区间每个位置上一的个数,再用第一个区间某一位上1的个数乘以第二个区间上那位上0的个数即为答案中该位的个数,算法其实不难,可好久没怎么写c++代码的我发现自己代码能力在不知不觉中下降了很多,一个是对数组指针不能运用memset,另一个是最后取模运算时少写了一个取模导致wa.。。。唉,还是要雷打不动学算法啊
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
LL s1[32],s2[32],mod;
void get(LL a,LL b,LL* p){
for(LL i=0;1;i++){
LL helpa=1LL<<i,helpb=1LL<<(i+1);
if(b<helpa)break;
LL aa=(a)/helpb*helpa+(((a)%helpb)>helpa?((a)%helpa):(0));
LL bb=(b+1)/helpb*helpa+(((b+1)%helpb)>helpa?((b+1)%helpa):(0));
p[i]=(bb-aa)%mod;
}
}
int main(){
LL T,a,b,c,d,ans;
cin>>T;
while(T--){
cin>>a>>b>>c>>d>>mod;
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
get(a,b,s1);
get(c,d,s2);
ans=0;
LL l1=b-a+1,l2=d-c+1;
for(int i=0;i<32;i++){
LL help=(1LL<<i);
ans=(ans+(s1[i]*(l2-s2[i])%mod+s2[i]*(l1-s1[i])%mod)%mod*help%mod)%mod;
//ans=(ans+((s1[i]*((l2-s2[i])%mod)%mod*((1LL<<i)%mod))%mod+(s2[i]*((l1-s1[i])%mod)%mod*((1LL<<i)%mod))%mod)%mod)%mod;
}
cout<<ans<<endl;
}
return 0;
}