ZJOI模拟 数字【数位dp】

6人阅读 评论(0) 收藏 举报
分类:

题目描述:

已知T,Lx,Rx,Ly,Ry,问在满足LxxRx,LyyRy,x or y=T的情况下,W=x and y有多少种取值。

解题思路:

数位 DP 会变得比较方便。
考虑一个数 W,我们要判断是否存在一组 (x,y) 使得 Lx ≤ x ≤ R x ,Ly ≤ y ≤ R y 且
x ∨ y = T,x ∧ y = W。
这个过程就是从高位到低位构造 (x,y) 的过程。
• 若 T 的当前位为 0,W 的当前位为 0,则 x 和 y 当前位都填 0。
• 若 T 的当前位为 0,W 的当前位为 1,则这是一个不合法的状况。
• 若 T 的当前位为 1,W 的当前位为 0,则当前位上可能 x 填 0,y 填 1,
也可能 x 填 1,y 填 0。
• 若 T 的当前位为 1,W 的当前位为 1,则 x 和 y 当前位都填 1。
x 和 y 各自已经填了的部分可能挨着Rx与 Ry或Lx与Ly的上界 (即 x 或 y 的已填部
分是 R x 或 R y或Lx或Ly 的前缀),也可能不挨,这样就有 3 × 3 = 9 种状态。
之前提到的第三种情况,同一步有两种填法,会造成分叉,所以,如果我们
要判断一个 W 是否可行,在从高位到低位确定 x,y 的过程中,就需要把这9
种状态分别可不可能出现记下来,这是一个 9 位的二进制数。
如何用 DP 的方式算出可行的 W 的种数呢?DP 的状态是当前已经考虑过
的位数和那个 9 位的二进制数。时间复杂度 O(logT),常数为 512。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=65;
ll T,l1,l2,r1,r2,f[N][1<<9];
int cnt,g[3][3];
pair<int,int> sta[9];
ll dfs(int i,int s)
{
    if(i==-1)return 1;
    if(f[i][s]!=-1)return f[i][s];
    ll res=0;
    for(int p=0;p<=(T>>i&1);p++)
    {
        int cur=0;
        for(int x=0;x<=1;x++)
            for(int y=0;y<=1;y++)if((x|y)==(T>>i&1)&&(x&y)==p)
                for(int k=0;k<9;k++)if(s>>k&1)
                {
                    int o1=sta[k].first,o2=sta[k].second;
                    ll k1,k2;
                    if(o1==0)k1=r1>>i+1;
                    else if(o1==1)k1=l1>>i+1;
                    else k1=(l1>>i+1)+1;
                    if(o2==0)k2=r2>>i+1;
                    else if(o2==1)k2=l2>>i+1;
                    else k2=(l2>>i+1)+1;
                    k1=(k1<<1)+x;k2=(k2<<1)+y;
                    if(k1>(r1>>i)||k1<(l1>>i))continue;
                    if(k2>(r2>>i)||k2<(l2>>i))continue;
                    if(k1==(r1>>i))o1=0;
                    else if(k1==(l1>>i))o1=1;
                    else o1=2;
                    if(k2==(r2>>i))o2=0;
                    else if(k2==(l2>>i))o2=1;
                    else o2=2;
                    cur|=1<<g[o1][o2];
                }
        if(cur)res+=dfs(i-1,cur);
    }
    return f[i][s]=res;
}
int main()
{
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    scanf("%lld%lld%lld%lld%lld",&T,&l1,&r1,&l2,&r2);
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)g[i][j]=cnt,sta[cnt++]=make_pair(i,j);
    memset(f,-1,sizeof(f));
    cout<<dfs(60,1)<<'\n';
    return 0;
}
查看评论

数位DP学习小结

一、学习心得体会 问题描述: 一般体现为,定义某种性质K,问某区间内具有K性质的数的个数 往往给的区间会很大,对区间内的每个数进行判断显然会超时 于是数位DP登场 数位DP,顾名思义,是对数字的每一位...
  • tomorrowtodie
  • tomorrowtodie
  • 2016年08月06日 21:03
  • 1646

51Nod 数字0到9的数量 (数位DP)

跟1009题类似: http://blog.csdn.net/since_natural_ran/article/details/72668443但是还是这道题考察能力强。 对于数字的考察...
  • Since_natural_ran
  • Since_natural_ran
  • 2017年06月06日 21:44
  • 258

数位dp(求1-n中数字1出现的个数)

题意:求1-n的n个数字中1出现的个数。 解法:数位dp,dp[pre][now][equa] 记录着第pre位为now,equa表示前边是否有降数字(即后边可不可以随意取,true为没降,...
  • xiefubao
  • xiefubao
  • 2014年05月11日 09:24
  • 1276

[ZJOI2010] 数字统计

[ZJOI2010] 数字统计时间限制:1 s 内存限制:128 MB 问题描述 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。 输入数据 输...
  • still_foolish
  • still_foolish
  • 2016年11月16日 23:17
  • 144

[BZOJ 1833] count 数字计数 数位DP(附数位DP总结)

题目传送门:【BZOJ 1833】题目大意:给定两个正整数 a 和 b,求在 [a,b] 中的所有整数中,每个数码 (digit,指 0-9 ) 各出现了多少次。其中 a ≤ b ≤ 1012^{12...
  • ArcCCcp
  • ArcCCcp
  • 2017年10月11日 12:15
  • 321

【数位DP】BZOJ3780数字统计

Time Limit: 10 Sec Memory Limit: 128 MB Description 小A正在研究一些数字统计问题。有一天他突然看到了一个这样的问题: 将[L..R][L.....
  • cqbztsy
  • cqbztsy
  • 2016年02月26日 12:20
  • 770

数位DP(数字和与倍数,uva 11361)

这道题拖了一整天,WA了无数发,感觉自己数位DP特别弱,其实可能就是因为自己数学比较弱,或者说在推导和代入繁杂的公式以及边界很粗糙的讨论上太不够严谨了,总是觉得大概对就对了,这在数学题上是非常致命的缺...
  • xl2015190026
  • xl2015190026
  • 2016年11月09日 11:49
  • 404

BZOJ 1833 [ZJOI 2010] 数字统计 (数位DP)

题目链接:BZOJ 1833 听说这道是一道水DP(Orz). 我到现在都不知道BZOJ上long long要用I64d输出,还是用lld输出Orz。应该是lld吧(DK)。反正我用I64d输出一...
  • SAI_D
  • SAI_D
  • 2015年03月18日 16:58
  • 392

count 数字计数 (数位dp)

给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。Input输入文件中仅包含一行两个整数a、b,含义如上所述。Output输出文件中包含一行10个整数,分别表示...
  • a1046765624
  • a1046765624
  • 2017年11月09日 21:56
  • 66

1042 数字0-9的数量【数位dp】

点击打开链接 给出一段区间a-b,统计这个区间内0-9出现的次数。 比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余...
  • zoro_n
  • zoro_n
  • 2017年07月01日 17:22
  • 149
    个人资料
    持之以恒
    等级:
    访问量: 2万+
    积分: 3401
    排名: 1万+
    友情链接
    文章分类