1、初探数位类统计问题,Keywords: 数位DP,二进制,异或。,Lazycal,基本知识,动规 l,r 意为 l=且=r的数 l,r) 意为 l=且 r的数 (l,r 意为 l 且=r的数 (l,r) 意为 l 且 r的数 其实方括号意味着取等,小括号意味着不取等,Content,引入 基本思想与方法 Hdu2089 Hdu3652 ural1057 test-09-07-p1 总结 参考文献,引入,“在信息学竞赛中,有一类与数位有关的区间统计问题。这类问题往往具有比较浓厚的数学味道,无法暴力求解,需要在数位上进行递推等操作。”刘聪浅谈数位类统计问题 这类问题往往需要一些预处理,这就用到了数
2、位DP。,基本思想与方法,OI中经常需要统计区间l,r的满足题意的数的个数,这往往可以转换成求0,r-0,l) 对于求区间0,n)有一个通用的方法。 对于一个小于n的数,肯定是从高位到低位出现某一位n的那一位。 如 n = 58 n为十进制数。x = 49 此时x的十位nx = 51 此时x的个位n,基本思想与方法,有了上述性质,我们就可以从高到低枚举第一次n对应位是哪一位。 这样之前的位确定了,之后的位就不受n的限制即从00.099.9,可以先预处理,然后这时就可以直接统计答案。,基本思想与方法,预处理f数组。 Fi,st 代表 位数为i(可能允许前导0。如00058也是个5位数),状态为s
3、t的方案数。这里st根据题目需要确定。 如i=4,fi,st也就是00009999的符合条件的数的个数(十进制) 决策第i位是多少(such as 09) Fi,st = Fi,st + fi1,st st为相对应的状态,Hdu2089,题目链接:http:/ 题目大意:给定区间n,m,求在n到m中没有“62“或“4“的数的个数。 如62315包含62,88914包含4,这两个数都是不合法的。 0n=m1000000,Hdu2089,参照刚刚所说的基本思路。预处理f数组,然后统计0,m - 0,n)。 fi,j代表开头是j的i位数中不含“62“或“4“的数有几个。 如f2,6包含60,61,6
4、3,65,66,67,68,69 f0,0 = 1; for i = 1 7for j = 0 9 /枚举第i位for k = 0 9 /枚举第i - 1位if j 4 and not(j = 6 and k = 2) fi,j = fi - 1,k + fi,j;,Hdu2089,如f2,6的转移 6? ? = 0,1,2,3,4,5,6,7,8,9 f2,6 = sum(f1,j) j = ?,Hdu2089,统计区间0,n 从高到低枚举哪一位比n小 如n = 4 5 6,0,0 0 0 1. 9 9,1,0 0 0 1. 9 9,0 0 0 1. 9 9,ans = ans + f3,0
5、,ans = ans + f3,1,ans = ans + f3,Hdu2089,统计区间0,n 从高到低枚举哪一位比n小 如n = 4 5 6,4 04 09,ans = ans + f2,04,Hdu2089,伪代码: /digiti 代表 n 从右到左第i位是多少,len是n有几位。 /如 n = 58 digit1 = 8 digit2 = 5for i = len 1 /枚举哪一位 4 and not (j = 2 and digiti + 1 = 6)ans = ans + fi,j; /情况合法if digiti = 4 or (digiti = 2 and digiti + 1
6、 = 6) break; /已经出现4或62,Hdu3652,题目链接:http:/ 题目大意:求小于n是13的倍数且含有13的数的个数。,Hdu3652,同样参照前面的思想,先预处理,再统计。 题目需要包含13,且被13整除,我们就设计状态fi,j,k,l代表 i位数中第一位是j的, 是否有包含13(k = 1 or 0), 模13余数是l的数有几个。,Hdu3652,决策第i位: for x = 0 9if k = 1 /要求要包含13fi,j,k,l = fi - 1,x,1,(l - j*10(i-1)%13;if j = 1 and x = 3 /已经有13了。fi,j,k,l =
7、fi,j,k,l + fi - 1,x,0,(l - j*10(i-1)%13;else /不要求包含13if not (j = 1 and x = 3) fi,j,k,l = fi - 1,x,0,(l - j*10(i-1)%13;,Hdu3652,统计小于n的合法的数有几个与上一题类似,只需要记录当前位之前的余数是多少,和是否已经出现了13 bit0 = 1; for (ll i = 1; i = 12; +i) biti = biti - 1*10; for (ll i = digit0,mod = 0; i; -i) for (ll j = 0; j digiti; +j) ans
8、+= fij1(13 - mod*biti%13)%13;if (t | (j = 3 ,ural1057,题目链接:http:/ 题目大意:求给定区间X,Y中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和。例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意:17 = 24+20, 18 = 24+21, 20 = 24+22. 1 X Y 2311,1 K 20, 2 B 10。,ural1057,所求的数为互不相等的幂之和,亦即其B进制表示的各位数字都只能是0和1。 因此,我们只需讨论二进制的情况,其他进制都可以转化为二进制求解。 本题区间满足区
9、间减法,因此可以进一步简化问题:令countij表示ij区间内合法数的个数,则countij=count0j-count0i-1。 换句话说,给定n,我们只需求出从0到n有多少个符合条件的数。,ural1057,首先预处理f fi,j代表i位二进制数中恰好有j个1的数的个数。 fi,j=fi-1,j+fi-1,j-1计算count0n 像前几题一样,一位一位枚举,只需要多记录后面需要的1的个数即可。 if digiti = 1 then ans = ans + fi,need need就是后面需要的1的个数。,ural1057,最后的问题就是如何处理非二进制。 对于询问n,我们需要求出不超过n
10、的最大B进制表示只含0、1的数:找到n的左起第一位非0、1的数位,将它变为1,并将右面所有数位设为1。 将得到的B进制表示视为二进制进行询问即可。 如n = (10204)9进制n = (10111)2进制,test-09-07-p1,题目大意:给定长度为n的序列Ai,求所有Ai xor Aj (ij)的值之和。,test-09-07-p1,还记得这题吧 现在看是不是很水 一位一位的处理。 统计这个数之前这一位有几个是0 然后根据当前位来处理。,拓展:spoj Sorted bit squence,题目链接:http:/www.spoj.pl/problems/SORTBIT or http:/ 题目大意:参照论文。 分析:参照论文。 ,Conclusion,“解决问题的核心思想就是“逐位确定”思想。“ “由于基本操作的复杂度是O(log(n)级别的,因此在处理一些较繁琐问题时,可以适当牺牲时间复杂度,对一些子问题采用二分、穷举等方法以降低思考和编程复杂度。” 对于求区间l,r的符合题目的数的个数,往往可以用0,r - 0,l),参考文献,算法合集之浅谈数位类统计问题刘聪 http:/