爱数学的小明又回来辣!看了上次大家解决问题的方法后觉得自己实在是太笨了,同时引来了同是数学爱好者的小红的嘲笑,自尊心极强的小明气不过,便和小红打个赌,让小红出一道数学题给小明写,如果小明能在一周内写出来,小红就请他吃下个星期的疯狂星期四,如果做不出来就要小明请她疯狂星期四。
但是这道题实在是太难啦,小明把自己关在房间里想了一周也没能想出来,明天就是赌约的截止日期了,小明非常想吃KFC,于是他想到了再次向你求助,并承诺只要帮他写出这道题就把小红请的KFC分你一半。
小红设立了两个函数 f ( x ) f(x) f(x)和 g ( x , m ) g(x,m) g(x,m) , f ( x ) f(x) f(x)的定义如下:
f ( x ) = ∏ i = 1 x 的位数 ( x m o d 1 0 i ) m o d ( x + 1 ) f(x)=∏_{i=1}^{x的位数}{(x\ mod\ 10^i)}\ mod\ (x+1) f(x)=∏i=1x的位数(x mod 10i) mod (x+1)
比如: f ( 2013 ) = ( 2013 ∗ 13 ∗ 13 ∗ 3 ) m o d 2014 f(2013)=(2013∗13∗13∗3)\ mod\ 2014 f(2013)=(2013∗13∗13∗3) mod 2014
g ( x , m ) g(x,m) g(x,m)的定义如下:
g ( x , m ) = { f ( g ( x , m − 1 ) ) , m > 1 f ( x ) , m = 1 g(x,m)= \begin{cases} f(g(x,m-1)),\quad m>1 \\[1ex] f(x), \quad m=1 \end{cases} g(x,m)={f(g(x,m−1)),m>1f(x),m=1
比如 g ( x , 2 ) = f ( f ( x ) ) g(x,2)=f(f(x)) g(x,2)=f(f(x)) 现在,要你求出 ∑ i = 1 m g ( x , i ) ∑^m_{i=1}{g(x,i)} ∑i=1mg(x,i)的值。
为了KFC,拼了!
第一行有一个数 T T T ( 1 ≤ T ≤ 20 1≤T≤20 1≤T≤20),代表一共有 T T T组数据。 接下来 T T T行有两个数 x , m x,m x,m( 1 ≤ x , m ≤ 1 0 9 1≤x,m≤10^9 1≤x,m≤109),代表 g ( x , m ) g(x,m) g(x,m)的两个参数
对于每行测试例输出一个数字。
2
3 4
4102 642
12
21262
把题中所述的函数实现出来,直接模拟过程即可。
AC代码如下:
#include
using namespace std;
long long f(long long x) {
long long sum = 1, t = 1;
do {
t *= 10;
sum = (sum * (x % t)) % (x + 1);
} while (x % t != x);
return sum;
}
long long g(long long x, long long m) {
if (m > 1) return f(g(x, m - 1));
else return f(x);
}
int main() {
long long t, x, m, sum, last;
cin >> t;
while (t--) {
cin >> x >> m;
sum = 0; last = x;
for (int i = 1; i <= m; i++) {
last = f(last);//唯一一个需要优化的地方,缓存上次计算结果,防止重复计算
sum += last;
}
cout << sum << endl;
}
return 0;
}