好题。有一个不知道怎么得出来的结论:
A(x,y)=(x−1) xor (y−1)+1
如果知道这个了就好做了,题目转换为求
∑ni=0∑mj=0[i xor j≤K]∗(i xor j+1)
然后就是数位DP了,x,y一起一位一位填,
f[i][0/1][0/1][0/1]
,
3
个
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100005,MOD=1e9+7;
typedef long long LL;
int Q,K,f1[35][2][2][2],f2[35][2][2][2]; //f1: 个数 f2: 和
LL Calc(int n,int m){
n--; m--; if(n<0||m<0) return 0;
memset(f1,0,sizeof(f1));memset(f2,0,sizeof(f2)); f1[32][0][0][0]=1;
for(int i=32;i>=2;i--)
for(int j1=0;j1<=1;j1++)
for(int j2=0;j2<=1;j2++)
for(int j3=0;j3<=1;j3++) if(f1[i][j1][j2][j3]){
int _x=(n>>i-2)&1,_y=(m>>i-2)&1,_k=(K>>i-2)&1;
for(int t1=0;t1<=(j1?1:_x);t1++)
for(int t2=0;t2<=(j2?1:_y);t2++){
if(!j3&&(t1^t2)>_k) continue;
(f1[i-1][j1|(t1<_x)][j2|(t2<_y)][j3|((t1^t2)<_k)]+=f1[i][j1][j2][j3])%=MOD;
(f2[i-1][j1|(t1<_x)][j2|(t2<_y)][j3|((t1^t2)<_k)]+=((LL)(f2[i][j1][j2][j3]<<1)+(LL)f1[i][j1][j2][j3]*(t1^t2))%MOD)%=MOD;
}
}
int res=0;
for(int j1=0;j1<=1;j1++)
for(int j2=0;j2<=1;j2++)
for(int j3=0;j3<=1;j3++)
(res+=(f2[1][j1][j2][j3]+f1[1][j1][j2][j3])%MOD)%=MOD;
return res;
}
int main(){
freopen("cf809C.in","r",stdin);
freopen("cf809C.out","w",stdout);
scanf("%d",&Q);
while(Q--){
int _x1,_y1,_x2,_y2; scanf("%d%d%d%d%d",&_x1,&_y1,&_x2,&_y2,&K); K--;
printf("%d\n",((Calc(_x2,_y2)-Calc(_x1-1,_y2)-Calc(_x2,_y1-1)+Calc(_x1-1,_y1-1))%MOD+MOD)%MOD);
}
return 0;
}