**惯于离经叛道中 体味心安理得,亦于按部就班中 痛感乏善可陈;我欺骗过 伪装过 失真过,但置我于死地者 必将赐我以后生。**
不容易啊~ ~ ~ ~ (>_<)~ ~ ~ ~ 这么多天来A的第一道题0 0。
题目大意如下:
样例输入:
3
1 5
3 9
8 8
样例输出:
2
2
0
数据规模:
L, R <=1e18 ,T <= 20
测试数据下载:链接: https://pan.baidu.com/s/1bpemuon 密码: u5fr
这道题具体的做法是这样的:我当时也想了一会。
这道题其实比较弱智:
首先我们使用狗眼观察法(/滑稽),是暴力打表法,把d【i】的函数打出来,这个应该都会。然后我们观察到一个惊人的性质。
d【i】的函数在1-9之间重复。
d【1】 = 1
d【2】 = 2
。。。
d【9】 = 9
d【10】= 1
一直这样下去
所以题目说:把A表示为x × d【x】的形式。
我们把x表示为9k+1,9k+2,……9k+9的形式
那么A = (9k+n)*n = 9kn+n^2 (n取1-9)
即:九个式子:
9k+1 (1)
18k+4(2)
27k+9(3)
36k+16(4)
45k+25(5)
54k+36(6)
63k+49(7)
72k+64(8)
81k+81(9)
然后对于一段区间我们就进行筛选算出可以有多少个k满足,当然其中会有重复的,其中(1)和(8)会重复,(2)和(7)会重复,(3)和(6)会重复,(4)和(5)会重复。
可能会有点抽象:
看代码就懂了
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define LL long long
using namespace std;
int t;
LL L, R, lf, rg;
LL cacl( LL L, LL R, LL M, LL pos ) {
if ( L > pos ) {
LL a = L - pos;
LL lf = a / M;
if ( a % M != 0 ) lf++;
pos = lf * M + pos;
}
if ( pos > R ) return 0;
LL len = R - pos + 1;
if ( len % M == 0 ) return len/M;
return len/M + 1;
}
int main() {
freopen("num.in","r",stdin);
freopen("num.out","w",stdout);
scanf( "%d", &t );
while ( t-- ) {
cin >> L >> R;
LL ans = 0;
ans += cacl( L, R, 9, 1 );
ans += cacl( L, R, 18, 4 );
ans += cacl( L, R, 27, 9 );
ans += cacl( L, R, 36, 16 );
ans += cacl( L, R, 45, 25 );
ans += cacl( L, R, 54, 36 );
ans += cacl( L, R, 63, 49 );
ans += cacl( L, R, 72, 64 );
ans += cacl( L, R, 81, 81 );
ans -= cacl( L, R, 72, 64 );
ans -= cacl( L, R, 54, 36 );
ans -= cacl( L, R, 126, 112 );
ans -= cacl( L, R, 180, 160 );
cout << ans << endl;
}
return 0;
}
啦啦。
最后附上我对你的思念。