【题解】codeforces776G Sherlock and the Encrypted Data
2017-03-01 21:05
239 查看
题目链接
题意:设x的16进制表示为xn-1xn-2...x1x0,定义h(x)=2^xn-1 or 2^xn-2 or...or 2^x1 or 2^x0。求l,l+1,...,r中满足x xor h(x)<x的数的个数。
分析:可以发现x xor h(x)<x是否成立只与h(x)的二进制表示下的最高位和x的二进制表示在该位的值有关(若为1则不等式成立)。因此以f
[p][i]表示长度为n、16进制表示下各位数字的最大值为p、二进制表示下第i位为1的16进制数的数目,以s
[p]表示长度为n、16进制表示下各位数字的最大值为p的16进制数的数目。则f
[p][i]与s
[p]均可递推预处理。
用calc(m)计算1,2,...,m中满足x^h(x)<x的数的个数。calc(m)的计算过程如下:
从高至底逐位扫描m的16进制表示,并统计答案。扫描至第k位时,设第k位数字为maxx且设前若干位的数字最大值为p0。枚举第k位的数字x(即此时统计前若干位与m相同,第k位数为x的这类数对答案的贡献),再枚举最后k-1位的各位数字最大值p,统计长度为k(k-1位即为长度为k)、16进制表示下各位数字的最大值为p、2进制表示下第max(p1,x,p)位为1的16进制数的数目即可(需要按max(p1,x,p)的值分类讨论)。
代码
题意:设x的16进制表示为xn-1xn-2...x1x0,定义h(x)=2^xn-1 or 2^xn-2 or...or 2^x1 or 2^x0。求l,l+1,...,r中满足x xor h(x)<x的数的个数。
分析:可以发现x xor h(x)<x是否成立只与h(x)的二进制表示下的最高位和x的二进制表示在该位的值有关(若为1则不等式成立)。因此以f
[p][i]表示长度为n、16进制表示下各位数字的最大值为p、二进制表示下第i位为1的16进制数的数目,以s
[p]表示长度为n、16进制表示下各位数字的最大值为p的16进制数的数目。则f
[p][i]与s
[p]均可递推预处理。
用calc(m)计算1,2,...,m中满足x^h(x)<x的数的个数。calc(m)的计算过程如下:
从高至底逐位扫描m的16进制表示,并统计答案。扫描至第k位时,设第k位数字为maxx且设前若干位的数字最大值为p0。枚举第k位的数字x(即此时统计前若干位与m相同,第k位数为x的这类数对答案的贡献),再枚举最后k-1位的各位数字最大值p,统计长度为k(k-1位即为长度为k)、16进制表示下各位数字的最大值为p、2进制表示下第max(p1,x,p)位为1的16进制数的数目即可(需要按max(p1,x,p)的值分类讨论)。
代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxl=16; LL s[maxl][maxl],f[maxl][maxl][maxl],px[maxl]; LL calc(LL m) { if (m==-1) return 0; LL ret=0; int p0=0,maxx; for (int n=maxl-1;n>=0;n--) { maxx=m/px &15; for (int x=0;x<maxx;x++) { if (!n) { int p1=max(p0,x); if (p1<4) ret+=((x&(1<<(p1-4*n)))!=0); else ret+=((m&(1<<p1))!=0); } else for (int p=0;p<maxl;p++) { int p1=max(p0,max(x,p)); if (p1<4*n) ret+=f[n-1][p][p1]; else if (p1<4*(n+1)) ret+=((x&(1<<(p1-4*n)))!=0)*s[n-1][p]; else ret+=((m&(1<<p1))!=0)*s[n-1][p]; } } p0=max(p0,maxx); } ret+=((m&(1<<p0))!=0); return ret; } int idx(char c) { if (c>='0'&&c<='9') return c-'0'; return c-'a'+10; } int main() { px[0]=1;for (int i=1;i<maxl;i++) px[i]=px[i-1]*16; for (int x=0;x<maxl;x++) { s[0][x]++; for (int i=0;i<4;i++) if ((1<<i)&x) f[0][x][i]++; } for (int n=0;n<maxl-1;n++) for (int x=0;x<maxl;x++) for (int p=0;p<maxl;p++) { int p1=max(p,x); s[n+1][p1]+=s [p]; for (int i=0;i<min(4*(n+1),maxl);i++) f[n+1][p1][i]+=f [p][i]; if (n<=2) for (int i=0;i<4;i++) if ((1<<i)&x) f[n+1][p1][i+4*(n+1)]+=s [p]; } int T;cin>>T; while (T--) { LL l=0,r=0; char L[20],R[20]; scanf("%s%s",L,R); int ll=strlen(L),rr=strlen(R); for (int i=ll-1;i>=0;i--) l+=idx(L[i])*px[ll-1-i]; for (int i=rr-1;i>=0;i--) r+=idx(R[i])*px[rr-1-i]; printf("%I64d\n",calc(r)-calc(l-1)); } return 0; }
相关文章推荐
- LeetCode题解——Path Sum
- [LeetCode]题解(python):060-Permutation Sequence
- LeetCode题解——Evaluate Reverse Polish Notation
- HDU 计算机学院大学生程序设计竞赛(2015’11)题解报告
- LeetCode题解 #8 String to Integer (atoi)
- 杭电“计算机学院大学生程序设计竞赛(2015’11)”题解【4-6】
- LeetCode题解 #2 Add Two Numbers
- [LeetCode]题解(python):066-Plus One
- Leetcode题解(九)
- NOI 2015 day1 t2 软件包管理器 题解&代码(c++)
- 【题解】SWJTU2015.12校队选拔题解
- 算法提高 学霸的迷宫 (题解)
- 【POJ 2104】K-th Number 题意&题解&代码(c++)
- 【leetcode题解】【再看一遍】【86】【M】Contains Duplicate III
- 【leetcode题解】【再来,动态规划】【H】【21.8】Burst Balloons
- [LeetCode]题解(python):072-Edit Distance
- BZOJ 1208 [HNOI2004] 宠物收养所 题解&代码
- [LeetCode]题解(python):078-Subsets
- [LeetCode]题解(python):089-Gray Code
- 【题解】QDUOJ.65.again and again