这道题题意十分简单,理解绝对没问题,唯一需要考虑的就是数据范围容易超时,经过 观察找到了一个规律可以让数据缩小一半,理论上感觉过不去,没想到A了,在这里现个丑,给大家介绍一下。
假设(20,10),根据题意,我们需要用10 mol (1~20)中每一个数,显然当大于10之后就不用考虑,余数必为10,当处于(10/2~10)中间的范围时余数恰好为9,8,7,6,5,4,3,2,1,0,因此只要求一下k与l/2的差就可以求出大于l/2的余数和了,剩下的暴力一下就行了。
代码如下:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #define LL long long using namespace std; int main() { int n,k; scanf("%d%d",&n,&k); int now=2; LL ans=0LL; while (now<=min(n,k)) { int d=k/now; int x=k/d; int a=k%now+k%x,b=x-now+1; ans=ans+((LL)a*b)/2LL; a=k%x+k%(min(n,k)+1),b=x-min(n,k); if (x>min(n,k)) ans=ans-((LL)a*b)/2LL; now=x+1; } if (n>k) ans=ans+((LL)(n-k)*k); cout<<ans<<endl; return 0; }
代码与思路稍有不符,还望见谅,同时希望能对您有所帮助,谢谢。