1257: [CQOI2007]餘數之和sum(數學分段統計)
阿新 • • 發佈:2019-01-29
如此一道水題,卻被邊界虐的很慘。
給定n和k,求sum = k mod 1 + k mod 2 + k mod 3 + … + k mod n(1<=n ,k<=10^9);
列舉商(n/i),之後分出商相同的若干個區間,注意到每個區間都是一個等差數列,分段求和即可;
對於商i
左端點 l = n/(i+1)+1;
右端點 r = min(m,n/i);
然後求出每段的總和 :(n%l+n%r)*(r-l+1)/2;
下一個 i = n / (n/(i+1));
然後累加即可;
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> using namespace std; int main() { long long n,m; scanf("%lld%lld",&m,&n); long long res(0); if(m>n) res+=(m-n)*n,m=n; for(long long i = 1; i <= n;) { long long r = min(m,n/i); long long l = (n/(i+1))+1; if(l<=r) res += (n%l+n%r)*(r-l+1)/2; if(i==n) break; i = n/(n/(i+1)); } cout<<res<<endl; return 0; }