There are three situations in the topic:
1,1<k<n;
2,k = = N;
3,k>n;
For the first case we can be divided into 1 to K and K to N two sub-problems to solve.
1.1,1 to K:
for (i = 1, sum = 0; I <= k; i + +) sum + = K%i;
1.2,K to n: sum = (n-k) *k;
And for the second situation is the first case (1). But in this case, the obvious tle .
The second case can also be divided into several small problems to solve:
2.1,1 to K/2:
for (i = K/2; I >=1; i--) sum+= K i;
2.2,K/2 to K:
k%k+ ((k-1) +1)% (k-1) +.......+ (K-M0) +m0)% (K-M0) of which M0 < K–m0, then M0<K/2, and because M0 is an integer so M0 = k/2–1;
Simply put: if k%i (i + +) has the same value as k/i (i + +), then k% i is a arithmetic progression for example:
K = +, I = 26
100% 26 = 22 100/26 = 3
100% 27 = 19 100/27 = 3
100% 28 = 16 100/28 = 3
100% 29 = 13 100/29 = 3
So sum = SUM (2.1) + SUM (2.2) ;
However, the time required for 2.1 to k=10^9 is also very large, so continue to optimize :
The same can be achieved for (i=k/2;i>=1;i--) can also be simplified into :
2.1.1,((K/2) *2+m1)% (K/2) + ((k/2-1) *2+m1+2)% (k/2-1) +...+ ((k/2-x) *2+m1+2*x)% (k/2-x);
Here m1=k% (K/2), because m0=k/2-1 in 2.2 , then m1 = k% (K/2), and x=k/6-1;
The 2.1.1 is a tolerance of 2 arithmetic progression;
2.1.2, for(i=k/3;i>=1;i--)
sum+=k%i;
As you can see, the original linear search can be split into a number of arithmetic progression. This allows the Jiancheng to be instantiated:
(k% (K/1) +k% (k/2+1)) * (K/1-K/2)/2+ (k% (K/2) +k% (k/3+1)) * (K/2-K/3)/2+ ... Set s=k/i;e=k/(i-1);
Then the appeal formula becomes: sum+= (k%e+k% (s+1)) * (e-s)/2; and its time complexity is only sqrt (k);
For the third case, both the k>n and the special case of the second case, the difference is to turn the prime minister into a k%n .
3.1,1<n<sqrt (k);
3.2,1<sqrt (k) <n;
So, as you can see from the above, we can divide sum into three parts:
1, sum+= (k%e+k% (s+1)) * (e-s)/2
2,for (i=1;i<=n&&i<=b;i++) sum+=k%i; where B = k/sqrt (k);
3, Sum + = (n-k)
#include <stdio.h> #include <math.h>long long Jos (Long long N,long long k) { long long sum=0,a= (long Long) sqrt (k), B=k/a,i; if (n>k) sum+= (n-k) *k; for (i=a;i>1;i--) { long s=k/i,e=k/(i-1); if (s>n) break; if (e>n) e=n; Sum + = (k%e+k% (s+1)) * (e-s)/2; } for (i=1;i<=n&&i<=b;i++) sum+=k%i; return sum;} int main () { long long n,k; while (scanf ("%i64d%i64d", &n,&k)!=eof) { printf ("%i64d\n", Jos (N,k)); } return 0;}
Uva1363-joseph ' s problem (number theory)