题解:AT_kupc2016_i 一坨日文看不懂思密达
upd on 26/7/15:修改代码错误,修改表述。感谢 xingchen666(link)。
把 Eli 先生及其分身称为“机器人”,Eli-
考虑只有一次询问怎么做。
考虑 DP。设
表示接下来这个机器人是否复制至少一个。当然后者能转移的前提是
不难发现一个机器人最终的等级不会很大。升到某个级别的所花时间是一个等差数列,也就是说它的等级最大
但是
注意到,让等级为
那么如果
否则如果
是的。因为这等价于
这样就解决了一次询问。
考虑多次询问。
注意到最终能直接或间接转移到
所以重新令
考虑答案。首先有
然后考虑最后
所以答案为
转移范围的话,第一维从
:::success[Code]
提交记录
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, P = 1e9 + 7;
int q, n, c;
int f[2][N], g[2][N];
signed main() {
for (int i = 498; i; -- i ) {
memset(f[i & 1], 0, sizeof f[i & 1]);
memset(g[i & 1], 0, sizeof g[i & 1]);
for (int j = 0; j < N; ++ j ) {
if (j >= i * 2) {
f[i & 1][j] = (f[i + 1 & 1][j - i] + f[i & 1][j - i]) % P;
g[i & 1][j] = (g[i + 1 & 1][j - i] + g[i & 1][j - i]) % P;
} else {
f[i & 1][j] = j;
g[i & 1][j] = 1;
}
}
}
cin >> q;
while (q -- ) {
cin >> n >> c;
cout << (1ll * f[1][n / c] * c + 1ll * g[1][n / c] * (n % c)) % P << '\n';
}
return 0;
}