题意

求区间[A,B]上的平衡数个数。平衡数是这样的数:在数的各个位上,奇数数字出现偶数次,偶数数字出现奇数次。

思路

很明显我们需要记录每一位出现的次数。分别记录是不明智的,而我们又只需要记录奇数次或者偶数次即可。所以我们可以用一个<=1024的数state表示0~9这10个数字出现的次数奇偶性,当奇数出现偶数次则相应位为1,当偶数出现奇数次相应位为1,最后判断是不是1023。但是这样它的初试状态不好确定。很明显初始时我们需要把state赋值成1010101010,即682(0次算偶次)。但是如果某些偶数位从始至终都没有出现,那么那一位最终为0显然不合理。我也没有想到什么更好的办法,只能再加一个1024的vis数表示0~9这10个数字是否出现过,但这样空间不够。后来想到一个优化是我们不必记录奇数是否出现过,因为它们初始就为1。所以可以把vis缩减到32,这样空间就足够了~问题边迎刃而解。

代码

[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, m) for (int i = begin; i < begin+m; i ++)
using namespace std;

typedef long long LL;
typedef vector <int> VI;
typedef set <int> SETI;
typedef queue <int> QI;
typedef stack <int> SI;

LL dp[20][1050][35][2];
VI num;
LL dfs(int pos, int state, int vis, bool flag, bool limit){
if (pos == -1){
bool ok = 1;
for (int i = 0; i <= 9; i ++)
if ((state & (1<<i)) == 0){
if (i % 2) {ok = 0; break;}
else if ((vis & (1 << (i/2))) != 0){
ok = 0; break;
}
}
return ok;
}
if (!limit && ~dp[pos][state][vis][flag]) return dp[pos][state][vis][flag];
int end = limit?num[pos]:9;
LL res = 0;
for (int i = 0; i <= end; i ++){
int next_state, next_vis;
if (i == 0 && !flag){
if (pos == 0){
next_state = state | 1;
next_vis = vis|1;
}
else{
next_state = state;
next_vis = vis;
}
}
else{
next_state = state ^ (1<<i);
if (i % 2 == 0)
next_vis = vis|(1<<(i/2));
else
next_vis = vis;
}
res += dfs(pos-1, next_state, next_vis, (!flag)&&i==0?flag:true, limit && (i==end));
}
return limit?res:dp[pos][state][vis][flag] = res;
}
LL cal(LL x){
num.clear();
while(x){
num.push_back(x%10);
x /= 10;
}
int len = num.size();
return dfs(len-1, 682, 0, 0, 1);
}
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
MEM(dp, -1);
int t;
scanf("%d", &t);
while(t --){
LL a, b;
scanf("%lld %lld", &a, &b);
printf("%lld\n", cal(b)-cal(a-1));
}
// for (int i = 100; i <= 1000; i ++){
// if (cal(i)-cal(i-1) == 1)
// printf("i = %d\n", i);
// }
return 0;
}
[/cpp]

SPOJ BALNUM ★(位压缩状态+数位DP)的更多相关文章

  1. SPOJ BALNUM Balanced Numbers (数位dp)

    题目:http://www.spoj.com/problems/BALNUM/en/ 题意:找出区间[A, B]内所有奇数字出现次数为偶数,偶数字出现次数为计数的数的个数. 分析: 明显的数位dp题, ...

  2. SPOJ BALNUM Balanced Numbers(数位DP+状态压缩)题解

    思路: 把0~9的状态用3进制表示,数据量3^10 代码: #include<cstdio> #include<map> #include<set> #includ ...

  3. SPOJ - BALNUM Balanced Numbers(数位dp+三进制状压)

    Balanced Numbers Balanced numbers have been used by mathematicians for centuries. A positive integer ...

  4. SPOJ - BALNUM - Balanced Numbers(数位DP)

    链接: https://vjudge.net/problem/SPOJ-BALNUM 题意: Balanced numbers have been used by mathematicians for ...

  5. BALNUM - Balanced Numbers(数位dp)

    题目链接:http://www.spoj.com/problems/BALNUM/en/ 题意:问你在[A,B]的闭区间内有几个满足要求的数,要求为每个出现的奇数个数为偶数个,每个出现的偶数个数为奇数 ...

  6. 数位dp备忘录

    hdu 4734:把限制值化为数组形式,逐位求解 hdu 4507:类似于上题,其中求平方和的方法很妙 SPOJ  BALNUM Balanced Numbers:经典数位dp,注意两点,1,不要把前 ...

  7. 【SPOJ 1182】 SORTBIT - Sorted bit squence (数位DP)

    SORTBIT - Sorted bit squence no tags Let's consider the 32 bit representation of all integers i from ...

  8. [kuangbin带你飞]专题十五 数位DP

            ID Origin Title   62 / 175 Problem A CodeForces 55D Beautiful numbers   30 / 84 Problem B HD ...

  9. Luogu3220 HNOI2012 与非 数位DP

    传送门 题意:给出$N$个范围在$[0,2^k-1]$的整数,定义位运算$NAND$为位运算$AND$的逆运算,求$[L,R]$中有多少数能成为若干个前面给出的整数.若干括号和$NAND$运算组成的表 ...

随机推荐

  1. 更新表中数据可以使用join

    1.在修改数据库的时候,每写完一条SQL语句都要加上一个分号,这样每句之间是有依赖关系的,上面执行不成功不会执行下面的语句. 2.在更新数据库中数据时可以使用join. 例如: update res ...

  2. C#:对含有中文的字符串进行MD5加密

    MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider(); var Sign = BitConverter.ToString(MD5. ...

  3. HDU - 2204 Eddy's爱好 (数论+容斥)

    题意:求\(1 - N(1\le N \le 1e18)\)中,能表示成\(M^k(M>0,k>1)\)的数的个数 分析:正整数p可以表示成\(p = m^k = m^{r*k'}\)的形 ...

  4. spring boot 使用属性加载顺序

    1.命令行中传入的参数 2.SPRING_APPLICATION_JSON中的属性.SPRING_APPLICATION_JSON是以JSON格式配置再系统环境变量中的内容 3.java:comp/e ...

  5. 微信公众平台Java版极速SDK

    JEEWX-API 是第一个微信公众平台Java版极速SDK,基于 jeewx-api 开发可以立即拥有简单易用的API,让开发更加轻松自如,节省更多时间 http://www.jeewx.com/

  6. HBuilder 详细使用方法 -------------参考 :http://www.runoob.com/w3cnote/hbuilder-intro.html

    HBuilder是DCloud(数字天堂)推出的一款支持HTML5的Web开发IDE.HBuilder的编写用到了Java.C.Web和Ruby.HBuilder本身主体是由Java编写,它基于Ecl ...

  7. 自定义圆形头像CircleImageView的使用和源码分析

    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0806/3268.html tools:context="com.ex ...

  8. Python笔记 #02# Inner workings of lists

    源:DataCamp datacamp 的 DAILY PRACTICE  + 日常收集. List of lists Subset and conquer Slicing and dicing Li ...

  9. c++第三十一天

    p159~p164:switch语句1.例程:统计文本中五个元音字母出现的次数.(利用输入输出重定向测试) $ a <input.txt>output.txt #include <i ...

  10. OpenStack之Keystone模块

    一.Keystone介绍 OpenStack Identity(Keystone)服务为运行OpenStack Compute上的OpenStack云提供了认证和管理用户.帐号和角色信息服务,并为Op ...