题意:

  平衡树定义为“一个整数的某个数位若是奇数,则该奇数必定出现偶数次;偶数位则必须出现奇数次”,比如 222,数位为偶数2,共出现3次,是奇数次,所以合法。给一个区间[L,R],问有多少个平衡数?

思路:

  这题比较好解决,只有前导零问题需要解决。如果枚举到011,那么其前导零(偶数)出现了1次而已,而此数11却是平衡数,所以不允许前导零的出现!

  由于dfs时必定会枚举到前导零,否则位数较少的那些统计不到。状态需要3维or2维也行,3维的比较容易处理,用一维表示数位出现次数,另一维表示数位是否已经出现过了,而剩下一维自然就是位数了。乱搞一下就行了。

 #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=; LL f[N][<<][<<], bit[N];
//[位数][状态][是否出现过] int isok(int s,int w)
{
if(!w) return ;
for(int i=; i<; i++)
{
if( i%== && (w&(<<i)) && (s&(<<i))== ) return ; //偶数
if( i%!= && (w&(<<i)) && (s&(<<i))!= ) return ;
}
return ;
} LL dfs(int i,int s,int w,int sum,bool e)
{
if(i==) return isok(s,w);
if(!e&&~f[i][s][w]) return f[i][s][w]; LL ans=;
int u= e? bit[i]: ;
for(int d=; d<=u; d++)
{
int ww=w, ss=s;
if( sum+d!= ) ww|=<<d,ss^=<<d;
ans+=dfs(i-, ss, ww, sum+d, e&&d==u);
}
return e? ans: f[i][s][w]=ans;
} LL cal(LL n)
{
if(n==) return ;
int len=, s=;
while(n) //拆数
{
bit[++len]=n%;
n/=;
}
return dfs(len,,,,true);
} int main()
{
//freopen("input.txt","r",stdin);
memset(f, -, sizeof(f));
LL L, R;int t;
cin>>t;
while( t-- )
{
cin>>L>>R;
cout<<cal(R)-cal(L-)<<endl;
}
return ;
} AC代码

AC代码

  为了省空间,以为只是标记一下偶数位就行了,奇数位若是出现偶数次,相当于没有出现(抵消)。注意要考虑0的情况,举例,如果出现数字11,抵消后状态为0,那么和出现数字0没有什么两样。然而过了样例却WA。

 #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=; LL f[N][<<][<<], bit[N];
//[位数][状态][是否出现过] int isok(int s,int w)
{
for(int i=; i<; i+=) //奇数
if( (s&(<<i)) )
return ;
for(int i=; i<&&w; i++) //偶数
if( (w&(<<i)) && (s&(<<*i))== )
return ;
//cout<<"123"<<endl;
return ;
} LL dfs(int i,int s,int w,int sum,bool e)
{
if(i==) return isok(s,w);
if(!e&&~f[i][s][w]) return f[i][s][w]; LL ans=;
int u= e? bit[i]: ;
for(int d=; d<=u; d++)
{
if(!sum&&!d) ans+=dfs(i-, s, w, , e&&d==u);
else
{
int ww=w;
if( d%== ) ww|=<<d/;
ans+=dfs(i-, s^(<<d), ww, sum+d, e&&d==u);
}
}
return e? ans: f[i][s][w]=ans;
} LL cal(LL n)
{
if(n==) return ;
int len=;
while(n) //拆数
{
bit[++len]=n%;
n/=;
}
return dfs(len,,,,true)-;
} int main()
{
//freopen("input.txt","r",stdin);
memset(f, -, sizeof(f));
LL L, R;int t;
cin>>t;
while( t-- )
{
cin>>L>>R;
cout<<cal(R)-cal(L-)<<endl;
}
return ;
}

WA代码

  进行一番YY之后AC了,因为像只出现偶数个奇数位的情况,而被抵消了,相当于没有出现过,而由于记录的时候并没有记录到底是否是前导零还是被抵消的那种,两种的结果是不一样的,只需要加多一维来区分开这两种就可以了。

 #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=; LL f[N][<<][<<][], bit[N];
//[位数][状态][是否出现过] int isok(int s,int w)
{
for(int i=; i<; i+=) //奇数
if( (s&(<<i)) )
return ;
for(int i=; i<&&w; i++) //偶数
if( (w&(<<i)) && (s&(<<*i))== )
return ;
return ;
} LL dfs(int i,int s,int w,bool sum,bool e)
{
if(i==) return isok(s,w);
if(!e&&~f[i][s][w][sum]) return f[i][s][w][sum]; LL ans=;
int u= e? bit[i]: ;
for(int d=; d<=u; d++)
{
if(==sum+d) ans+=dfs(i-, , , , e&&d==u);
else
{
int ww=w;
if( d%== ) ww|=<<d/;
ans+=dfs(i-, s^(<<d), ww, sum+d, e&&d==u);
}
}
return e? ans: f[i][s][w][sum]=ans;
} LL cal(LL n)
{
if(n==) return ;
int len=;
while(n) //拆数
{
bit[++len]=n%;
n/=;
}
return dfs(len,,,,true)-;
} int main()
{
//freopen("input.txt","r",stdin);
memset(f, -, sizeof(f));
LL L, R;int t;
cin>>t;
while( t-- )
{
cin>>L>>R;
cout<<cal(R)-cal(L-)<<endl;
}
return ;
}

AC代码

SPOJ BALNUM Balanced Numbers 平衡数(数位DP,状压)的更多相关文章

  1. CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)

    问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...

  2. 【HDU】4352 XHXJ's LIS(数位dp+状压)

    题目 传送门:QWQ 分析 数位dp 状压一下现在的$ O(nlogn) $的$ LIS $的二分数组 数据小,所以更新时直接暴力不用二分了. 代码 #include <bits/stdc++. ...

  3. SPOJ BALNUM - Balanced Numbers - [数位DP][状态压缩]

    题目链接:http://www.spoj.com/problems/BALNUM/en/ Time limit: 0.123s Source limit: 50000B Memory limit: 1 ...

  4. SPOJ BALNUM Balanced Numbers (数位dp)

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

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

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

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

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

  7. SPOJ10606 BALNUM - Balanced Numbers(数位DP+状压)

    Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a ...

  8. 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP

    [BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...

  9. hdu3709 (平衡数) 数位DP

    Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

随机推荐

  1. POJ-3069

    Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10994   Accepted: 5555 D ...

  2. 2019计蒜之道初赛4 B. 腾讯益智小游戏—矩形面积交(简单)(矩形交集)

    B. 腾讯益智小游戏—矩形面积交(简单) 1000ms 262144K   腾讯游戏开发了一款全新的编程类益智小游戏,最新推出的一个小游戏题目是关于矩形面积交的.聪明的你能解出来吗?看下面的题目接招吧 ...

  3. 蓝桥杯 正则问题(dfs)

    1607: 正则问题 时间限制: 1 Sec  内存限制: 256 MB提交: 34  解决: 13[提交][状态][讨论版] 题目描述 考虑一种简单的正则表达式:只由 x ( ) | 组成的正则表达 ...

  4. IDEA如何找到接口的实现类

    如何找到接口的实现类 (IDEA))在ApplicationContext上右击 Diagrams ->show diagram 可以看到继承关系: 在ApplicationContext上右击 ...

  5. 安装wepack

    安装webpack之前要安装node.js 1.安装webpack运行 npm install webpack -g 和npm install webpack-cli -g npm install w ...

  6. Unity ShaderLab 光照随笔

    unity camera默认3种渲染路径,unity5.50里面有4种 camera Rendering Path 1 vertexLit(逐顶点,一般在vert中处理)  2 forward (前向 ...

  7. 求10000以内n的阶乘(openjudge 2923)

    求10000以内n的阶乘 总时间限制:  5000ms 内存限制:  655360kB 描述 求10000以内n的阶乘. 输入 只有一行输入,整数n(0<=n<=10000). 输出 一行 ...

  8. (三)siege的使用

    学习: ELK——http://dockone.io/article/3655 docker——http://www.testclass.net/docker/ Android Monkey压力测试— ...

  9. BitMap的原理以及运用

    位图(Bitmap),即位(Bit)的集合,是一种数据结构,可用于记录大量的0-1状态,在很多地方都会用到,比如Linux内核(如inode,磁盘块).Bloom Filter算法等,其优势是可以在一 ...

  10. SqlConnectionStringBuilder的用法

    SqlConnectionStringBuilder提供了一个很好的构建SQL连接字串的方式.不多说,见代码: SqlConnectionStringBuilder builder = new Sql ...