250pt:水题.
仰慕戴牛手速帝:
600pt:题目逻辑有点复杂,不过对于那些经验丰富的老油子,冷静思考的话难度不是太大.
关键是把题目给的流程代码化简,然后找出可以优化的地方.
截止比赛结束,我能看到的是,bag2,3,4是没有用的,本质是在bag 0 和 1 的变化,还有就是过程有点类似辗转相除法.
然后在群里已经给出了解法和相关题源.
流程最终的最简形式大概是:预处理出来每次循环不变的运算,然后就会发现
循环其实是求 sum(N/i) (2 <= i <= D, 这里D是N最小的约数),当时白神cha大素数也是这个原因.
如果比赛的时候你已经到了这里,这个题就可以完美解决了,求sum的优化不是很难想.
代码:
---------------------------------------------------------------------------------------------------
LL get_divisor(LL x)
{
LL t = sqrt(x + EPS);
for(LL i = 2; i <= t; i++)
{
if(x % i == 0) return i;
}
return x;
}
int computeAnswer(long long N)
{
if(0 == N || 1 == N) return -1;
LL ans = 1;
LL D = get_divisor(N);
ans = (ans + ((N * 4 + 1) % MOD) * ((D - 2) % MOD)) % MOD;
ans = (ans + 3 * N) % MOD;
LL i = 2;
while(i <= D)
{
LL a = N / i;
LL b = min(N / a, D);
ans = (ans + (a + 1)* (b - i + 1)) % MOD;
i = b + 1;
}
return ans;
}
---------------------------------------------------------------------------------------------------
900pt:没看.