SPOJ BALNUM Balanced Numbers 平衡数(数位DP,状压)
题意:
平衡树定义为“一个整数的某个数位若是奇数,则该奇数必定出现偶数次;偶数位则必须出现奇数次”,比如 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,状压)的更多相关文章
- CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)
问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...
- 【HDU】4352 XHXJ's LIS(数位dp+状压)
题目 传送门:QWQ 分析 数位dp 状压一下现在的$ O(nlogn) $的$ LIS $的二分数组 数据小,所以更新时直接暴力不用二分了. 代码 #include <bits/stdc++. ...
- SPOJ BALNUM - Balanced Numbers - [数位DP][状态压缩]
题目链接:http://www.spoj.com/problems/BALNUM/en/ Time limit: 0.123s Source limit: 50000B Memory limit: 1 ...
- SPOJ BALNUM Balanced Numbers (数位dp)
题目:http://www.spoj.com/problems/BALNUM/en/ 题意:找出区间[A, B]内所有奇数字出现次数为偶数,偶数字出现次数为计数的数的个数. 分析: 明显的数位dp题, ...
- SPOJ - BALNUM Balanced Numbers(数位dp+三进制状压)
Balanced Numbers Balanced numbers have been used by mathematicians for centuries. A positive integer ...
- SPOJ - BALNUM - Balanced Numbers(数位DP)
链接: https://vjudge.net/problem/SPOJ-BALNUM 题意: Balanced numbers have been used by mathematicians for ...
- SPOJ10606 BALNUM - Balanced Numbers(数位DP+状压)
Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a ...
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- hdu3709 (平衡数) 数位DP
Balanced Number Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
随机推荐
- GridView ,后台修改 跟新完毕,前端 未跟新处理
//Response.Redirect(Request.Url.ToString());//重新定位 GridView_dept.DataBind(); //重新绑定都可以
- 符号分割的字符串转换为XML
把某一符串分割的字符串转换为 XML格式: DECLARE @str NVARCHAR(MAX) = N'fd,re,45,tyu,976,qwer,gdsg,uyt' DECLARE @xml XM ...
- 字节码操作-Javaassist
下面就是一个具体的demo来介绍利用Javaassist库来创建类,不过要先在工程里面导入Javaassist的架包, package JavaAasist; import java.lang.ref ...
- 51nod1107(逆序对数&归并排序)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1107 题意:中文题诶- 思路:通过题意可以发现对于两点p1(x ...
- [Swift]Xcode实际操作
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- HTTPRunner实践二——参数化之生成UUID
接口测试中,需要使用到UUID,用来生成唯一ID. 1.什么是UUID UUID是128位的全局唯一标识符,通常由32字节的字符串表示.它可以保证时间和空间的唯一性,也称为GUID,全称为:UUID ...
- path不相等的子集,父级
SELECT a.path,b.path from comm_department_temp a INNER JOIN comm_department_temp b on a.id=b.parent_ ...
- blur和focus的运用
这两个事件不仅仅只能运用与input.span之类的元素.还可以运用于window. 可以切换title. 当切换当前页面时,改变title的文字为‘离开了’. <!DOCTYPE html&g ...
- Js $.merge() 函数(合并两个数组内容到第一个数组)
定义和用法 $.merge() 函数用于合并两个数组内容到第一个数组. 语法 $.merge( first, second ) 参数 描述 first Array类型 第一个用于合并的数组,合并后 ...
- Python网络编程之基础
计算机网络基础 网络到底是什么?计算机之间如何通信的? 早期:联机 以太网:局域网与交换机 ******广播 主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发, 所 ...