[数位DP] Codeforces 809C Round #415 (Div. 1) C. Find a car

来源:互联网 发布:整理桌面软件 编辑:程序博客网 时间:2024/05/22 01:45

题目梗概

有一个1e91e9的矩阵,记第x行y列的元素为(x,y)
(x,y)的值,定义为所有(i,y),(x,j)(1≤i

解题思路

这种题目一看就是有一个结论。

通过一些奇怪的途径我知道了结论,位于(x,y)的数字为((x1)xor(y1))+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 longusing 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;}
阅读全文
0 0
原创粉丝点击