题目梗概
有一个
1e9∗1e9
的矩阵,记第x行y列的元素为(x,y)
(x,y)的值,定义为所有(i,y),(x,j)(1≤i
解题思路
这种题目一看就是有一个结论。
通过一些奇怪的途径我知道了结论,位于(x,y)的数字为 ((x−1)xor(y−1))+1
运用容斥原理我们只需要考虑到(1,1)的矩阵的数字和。
定义 f[i][j][k][t] 表示前i位,x,y,x^y的值是否紧贴给定值。
开 g[i][j][k][t] 存储方案数。
转移时注意不超过范围。
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const int tt=1000000007;
LL f[35][2][2][2],g[35][2][2][2];
int T,x1,y1,x2,y2,K;
LL work(int x,int y){
if (x<0||y<0) return 0;
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
f[32][1][1][1]=1;
for (int i=32;i>=1;i--)
for (int j1=0;j1<2;j1++)
for (int j2=0;j2<2;j2++)
for (int j3=0;j3<2;j3++) if (f[i][j1][j2][j3])
for (int a1=0;a1<2;a1++)
for (int a2=0;a2<2;a2++){
if (j1&&a1>((x>>i-1)&1)) continue;
if (j2&&a2>((y>>i-1)&1)) continue;
if (j3&&(a1^a2)>((K>>i-1)&1)) continue;
int A=(j1&&a1==((x>>i-1)&1)),B=(j2&&a2==((y>>i-1)&1)),C=(j3&&(a1^a2)==((K>>i-1)&1));
(f[i-1][A][B][C]+=f[i][j1][j2][j3])%=tt;
(g[i-1][A][B][C]+=g[i][j1][j2][j3]*2+(a1^a2)*f[i][j1][j2][j3])%=tt;
}
LL ans=0;
for (int j1=0;j1<2;j1++)
for (int j2=0;j2<2;j2++)
for (int j3=0;j3<2;j3++)
(ans+=f[0][j1][j2][j3]+g[0][j1][j2][j3])%=tt;
return ans;
}
int main(){
freopen("exam.in","r",stdin);
freopen("exam.out","w",stdout);
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&K);
x1--;y1--;x2--;y2--;K--;
printf("%lld\n",((work(x2,y2)-work(x2,y1-1)-work(x1-1,y2)+work(x1-1,y1-1))%tt+tt)%tt);
}
return 0;
}