범위의 모 드 연산 합계를 찾은 다음 a and b
을 입력하면 sum of b%i where i ranges from 1 to a
값을 어떻게 찾을 수 있습니까? 한 가지 방법은 1에서 a까지의 모든 값을 반복하는 것이지만 효율적인 방법이 있습니까? (O (n)보다?) 예 : a = 4 및 b = 5 인 경우 ans = 5 % 1 + 5 % 2 + 5 % 3 + 5 % 4 = 4 감사합니다. i > b
들어숫자가 두 자리이면
4
A
답변
4
우리 합계의 일부가 용이하게 (a >= b
경우, 0, 그렇지 (a-b)*b
) 일정한 시간이 산출되도록, b % i == b
있다.
i <= b
의 부품은 계산되지 않습니다 (i == b
은 0이므로 무시할 수 있음). 당신은 i <= sqrt(b)
를 들어
- (SQRT (B)) 단계 O에서 그렇게
b % i
을 계산하고k = floor(b/i)
, 다음b % i == b - k*i
및k < sqrt(b)
하자,i > sqrt(b)
를 들어 - 합계를 추가 할 수 있습니다. 따라서
k = 1
에서ceiling(sqrt(b))-1
까지는hi = floor(b/k)
과lo = floor(b/(k+1))
으로 지정하십시오.hi - lo
숫자가i
이고k*i <= b < (k+1)*i
인 경우 해당 숫자의b % i
의 합은sum_{ lo < i <= hi } (b - k*i) = (hi - lo)*b - k*(hi-lo)*(hi+lo+1)/2
입니다.
a <= sqrt(b)
의 경우 a
에 멈추는 첫 번째 글 머리 기호 만 적용됩니다. sqrt(b) < a < b
인 경우 두 번째 글 머리표에서 k = floor(b/a)
에서 ceiling(sqrt(b))-1
까지 실행하고 k
에서 a
까지의 상한선을 조정하십시오.
전체 복잡성 O (분 (a, sqrt (b))).
코드 (C) :
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
unsigned long long usqrt(unsigned long long n);
unsigned long long modSum(unsigned long long a, unsigned long long b);
int main(int argc, char *argv[]){
unsigned long long a, b;
b = (argc > 1) ? strtoull(argv[argc-1],NULL,0) : 10000;
a = (argc > 2) ? strtoull(argv[1],NULL,0) : b;
printf("Sum of moduli %llu %% i for 1 <= i <= %llu: %llu\n",b,a,modSum(a,b));
return EXIT_SUCCESS;
}
unsigned long long usqrt(unsigned long long n){
unsigned long long r = (unsigned long long)sqrt(n);
while(r*r > n) --r;
while(r*(r+2) < n) ++r;
return r;
}
unsigned long long modSum(unsigned long long a, unsigned long long b){
if (a < 2 || b == 0){
return 0;
}
unsigned long long sum = 0, i, l, u, r = usqrt(b);
if (b < a){
sum += (a-b)*b;
}
u = (a < r) ? a : r;
for(i = 2; i <= u; ++i){
sum += b%i;
}
if (r < a){
u = (a < b) ? a : (b-1);
i = b/u;
l = b/(i+1);
do{
sum += (u-l)*b;
sum -= i*(u-l)*(u+l+1)/2;
++i;
u = l;
l = b/(i+1);
}while(u > r);
}
return sum;
}
+0
덕분에 자세한 설명을 볼 수 있습니다 :) – pranay
관련 문제
- 1. 개미 : 두 숫자가 같은지 확인하십시오.
- 2. 숫자가
- 3. 두 자리 숫자가 다른 고유 코드 생성
- 4. "echo"두 개의 숫자가 같지만! =이 참입니까?
- 5. 숫자가 두 열로 나타나는 총 횟수 찾기
- 6. 임의의 숫자가
- 7. 레일, 숫자가 연속적인지 평가
- 8. 파이썬에서 숫자가 합리적인지 확인
- 9. 그룹에 숫자가 있습니까?
- 10. 두 자리 숫자가 같지 않은 숫자에 대한 반복
- 11. 두 개의 숫자가 올바르게 작동하지 않는 자바 스크립트 함수
- 12. EXCEL : 숫자가 두 번 이상 나타난 최대 값 반환
- 13. 동일한 숫자가 배열에 두 번 나타나면 찾을 수 있습니까?
- 14. Android - 셀 번호에 두 개의 숫자가 나타나는 시간 계산
- 15. 다른 열로 두 테이블에서 선택하기, 하나의 테이블에 숫자가 필요함
- 16. 숫자가 반복되지 않는 두 정수 사이의 수를 찾기위한 알고리즘
- 17. Jquery 버그? 두 숫자가 곱한 후에 긴 십진수
- 18. 숫자가 내림차순으로 오름차순
- 19. 숫자가 증가하지 않을 것입니다.
- 20. 숫자가 거꾸로 표시됩니까?
- 21. 숫자가 적은 배열로보기?
- 22. 숫자가 -, + 또는 x인지 확인
- 23. 숫자가 파이썬으로 소수인지 알아보기
- 24. 숫자가 자동으로 문자열로 변경되었습니다.
- 25. 숫자가 0으로 시작되는 변환
- 26. 숫자가 완전하거나 소수인지를 결정하십시오.
- 27. 클릭시 ID의 숫자가 증가합니다.
- 28. 숫자가 포함 된 단어
- 29. 숫자가 값을 변경하고 있습니다.
- 30. BackgroundWorker 스레드의 숫자가 맞습니까?
그것만 경우에 대한 해결책을 찾는 것으로 충분은 B \ sum_ {I = B}^소위 = a (a-1)/2-b (b-1)/2이다. –