zoukankan      html  css  js  c++  java
  • 洛谷CF809C Find a car(数位DP)

    洛谷题目传送门

    通过瞪眼法发现,(a_{i,j}=(i-1) ext{ xor }(j-1)+1)

    二维差分一下,我们只要能求$sumlimits_^xsumlimits_^y[i extjle k]$就好了。

    比较套路的数位DP。

    从高位往低位做,设$f[t][0/1][0/1][0/1]$表示到第$t$位,$i,j,i extj$已确定的值是否卡到$x,y,k$前$t$位的上界的方案数和权值和。

    每一位的转移都是一个小讨论:如果之前卡到上界,这一位可以接着卡,或者如果这一位的上界是$1$,就可以填$0$转移到不卡上界。如果之前不卡了,那么这一位随便选。

    注意到最开始的式子里有一个$+1$,所以要输出$sum$权值和+方案数。

    下面的代码使用了压位和define可能会比较丑

    #include<bits/stdc++.h>
    #define R register int
    using namespace std;
    const int YL=1e9+7;
    int t,fc[8],fs[8],gc[8],gs[8];
    inline int in(){R x;scanf("%d",&x);return x;}
    inline void M(R&x){if(x>=YL)x-=YL;}
    #define T(x,u,v) if(i>1||w==x)Trans(i>>1,li,u,v,i>1?w^x:w)
    void Trans(R i,R li,R u,R v,R w){//暴搜转移
        if(!i){
            if(w)gs[v]=(gs[v]+fc[u]*(long long)t)%YL;
            return M(gc[v]+=fc[u]),M(gs[v]+=fs[u]);
        }
        if(i&li){T(0,u,v|i);T(1,u,v);}//讨论开始
        else T(0,u,v);
        T(0,u|i,v|i);
        T(1,u|i,v|i);
    }
    int Dp(R n,R m,R k){
        if(n<0||m<0)return 0;
        memset(fc,0,32);fc[0]=1;
        memset(fs,0,32);
        for(t=1<<30;t;t>>=1){
            Trans(4,!!(n&t)*4|!!(m&t)*2|!!(k&t),0,0,0);
            memcpy(fc,gc,32),memset(gc,0,32);
            memcpy(fs,gs,32),memset(gs,0,32);
        }
        R s=0;
        for(R i=0;i<8;++i)M(s+=fs[i]),M(s+=fc[i]);
        return s;
    }
    int main(){
        for(R q=in();q--;){
            R x1=in()-2,y1=in()-2,x2=in()-1,y2=in()-1,k=in()-1;
            cout<<((Dp(x2,y2,k)-Dp(x1,y2,k)-Dp(x2,y1,k)+Dp(x1,y1,k))%YL+YL)%YL<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    PHP实现html字符实体转汉字
    利用 secureCRT 直接上传下载文件 (sz,rz)
    CentOS安装scp命令
    以Apache模块的方式编译安装php-5.5.4
    编译安装 apache 2.4.6
    协方差Covariance的表述推导
    Java _ JDK _ Arrays, LinkedList, ArrayList, Vector 及Stack
    Java_一些特殊的关键字详(?)解
    Java_你应该知道的26种设计模式
    排序与搜索一览
  • 原文地址:https://www.cnblogs.com/flashhu/p/10540269.html
Copyright © 2011-2022 走看看