洛谷CF809C Find a car(数位DP)

洛谷题目传送门

通过瞪眼法发现,ai,j=(i1) xor (j1)+1

二维差分一下,我们只要能求i=0xj=0y[i xor jk]就好了。

比较套路的数位DP。

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

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

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

下面的代码使用了压位和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;
}
posted @   Flash_Hu  阅读(374)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2018-03-17 洛谷P4172 [WC2006]水管局长 (LCT,最小生成树)
点击右上角即可分享
微信分享提示
西雅图
17:14发布
西雅图
17:14发布
6°
东南风
3级
空气质量
相对湿度
84%
今天
3°/13°
周六
小雨
6°/15°
周日
中雨
4°/15°