[牛客每日一题](枚举优化,整数分块) NC13221数码
题目描述
给定两个整数 l 和 r ,对于所有满足1 ≤ l ≤ x ≤ r ≤ 10^9 的 x ,把 x 的所有约数全部写下来。对于每个写下来的数,只保留最高位的那个数码。求1~9每个数码出现的次数。
输入描述:
一行,两个整数 l 和 r (1 ≤ l ≤ r ≤ 10^9)。
输出描述:
输出9行。
第 i 行,输出数码 i 出现的次数。
示例1
输入
1 4
输出
4
2
1
1
0
0
0
0
0
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
LL l, r, a[20], b[20];
int GetHead(int x)
{
int h = 0 ;
while (x){
h = x % 10;
x /= 10;
}
return h;
}
void f(LL r, LL *a)
{
for (int i = 1; i <= r/i; i++) //枚举一个因子a
{
int b = r/i; //b的范围左界是i+1(为了不算重复),右界是r/i
for (int j = 1; j <= r; j *= 10) //枚举位数(直接用1后面若干个0,方便后面计算)
{
for (int k = 1; k <= 9; k++) // 枚举首位数
{
int x = max(j*k, i+1); //x是最高位为k的时候的下界
int y = min((j *(k+1)) -1, b); //y是上界
if (y-x>=0) a[k] += y-x+1; //这个区间存在,算个数
}
}
int h = GetHead(i); //算a的首位
a[h] += b-i+1; //算用了多少个a
}
}
int main()
{
scanf("%lld%lld", &l, &r);
f(r, a);
f(l - 1, b);
for(int i = 1; i <= 9; ++i)
printf("%lld\n", a[i]-b[i]);
return 0;
}
本文来自博客园,作者:泥烟,CSDN同名, 转载请注明原文链接:https://www.cnblogs.com/Knight02/p/16255360.html