题目描述:
题目传送门:https://ac.nowcoder.com/acm/contest/5086/E
样例说明:x=2,3,4时next(x)=4;x=5,6,7时next(x)=7,和位4+4+4+7+7+7=33.
题目分析:
因为幸运数字只由两个数字构成,如果直接暴力的话由于数据范围比较大,会超时。所以通过一些简单的推导不难看出,这个数字如果有n位的话,n位的幸运数字共有2^n种结果(参考二进制,0相当于4,1相当于7)。题目所给的数据范围种也就是最多有1024个幸运数字,我们可以把幸运数字单独保存到一个数组中,然后判断这个数字属不属于所给的区间,如果属于的话就加上这个数,不属于的话就跳过,继续判断下一个。
那么新的问题又来了,怎么找出并保存这1024个数字呢?经过大佬的指点,树状数组!! 具体示意图如下:
对于任意一个父亲节点的左孩子,其值等于父亲节点的值 * 10+4,右孩子的值等于父亲节点的值 * 10+7,这样子建树是不是容易多了?
AC代码:
#include <bits/stdc++.h>
#define PI 3.141592653589793238462643383279
using namespace std;
typedef long long ll;
int main()
{
ll k=0,s=0,l,r,p=1;
ll a[1050]={0};
for(int i=1;i<=1024;i++)
{
int t=i/2+1,q=i%2?4:7;
a[i]=10*a[i-t]+q;
}
cin>>l>>r;
for(int i=0;i<=1024;i++)
{
if(a[i]>=l)
{
for(;l<=a[i];l++)
{
s+=a[i];
if(l==r)break;
}
if(l==r)break;
}
}
cout<<s<<endl;
return 0;
}
别忘了数据类型要开long long呀~