您的位置:首页 > 其它

【题解】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)的值分类讨论)。

代码

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces 数位dp