分析题目
从题目可以看出给的一串数非常有规律,我们可以在树状数组每个位置把对应的数字插入就好了。
然后就是简单的求和了,没什么说的,直接看代码。
AC代码
#include<iostream>
using namespace std;
const int N=1e6+10;
int tr[N];
int lowbit(int x)//树状数组最低位
{
return x&-x;
}
void add(int x,int d)//对应位置添加数组
{
for(;x<=N;x+=lowbit(x)) tr[x]+= d;
}
int sum(int x)//求和
{
int sum=0;
for(;x;x-=lowbit(x)) sum+=tr[x];
return sum;
}
int main()
{
int t;
scanf("%d",&t);
int now=1;//现在应该插入哪个数字
int idx=1;//当前这个数字插入了多少次
for(int i=1;i<N;)
{
int j=now;
int a[10],po=1;//a数组用来表示now的每一位各是多少
while(j)
{
a[po++]=j%10;
j/=10;
}
for(int pos=po-1;pos>=1;pos--)
{
add(i,a[pos]);//插入每一位的数字
i++;
}
if(now==idx)//当前这个数字插入的次数已经足够多了,换下一个数字
{
now++;
idx=0;
}
idx++;
}
while(t--)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",sum(r)-sum(l-1));//用sum(r)表示1-r的数字之和,sum(l-1)表示1-(l-1)的数字之和,相减即可得到l-r的数字之和
}
}