오로라 함수 와 최대 공약수 의 응용
: N(N ), 1~N X X GCD(X,N)>=M, .
분석: 이것 은 통계 유형의 문제 입 니 다. 비교적 쉽게 생각 할 수 있 는 해법 은 GCD (X, N) 의 값 을 매 거 하 는 것 입 니 다. 매 거 진 GCD (X, N) 의 값 d 에 대해 N = p * d, X = q * d 라면 GCD (X, N) = d 는 반드시 p, q 의 호환성 이 있 고 X < = N 이 있 으 면 q < = p 입 니 다. 이런 q 의 개 수 는 p 의 오로라 함수 에 대응 합 니 다. 즉 GCD (X, N) = d 의 X 개 수 는 N / d 의 오로라 함수 값 을 만족 시 킵 니 다.
응용 1: N 과 M 을 주 고 몇 개의 X 가 1 < = X < = N 을 만족 시 키 는 지, 그리고 (X, N) > = M 을 만족 시 키 는 지 구하 십시오.
문제 풀이 방향: 이 문제 에 대해 서 는 문제 의 뜻 을 만족 시 키 는 X 의 개수 만 구하 기 때문에 최대 공약수 d 를 매 거 할 수 있 고 gcd (X, N) = d 를 만족 시 키 는 X 의 개 수 는 N / d 의 오로라 함수 입 니 다. 이 d 에 대응 하 는 N / d 의 오로라 함수 값 을 구 하면 됩 니 다.
LL res=0,i;
for(i=1;i*i<=n;i++)
{
if(n%i==0)
{
if(i>=m)
res+=euler(n/i)*i;
if(i*i!=n&&n/i>=m)
res+=euler(i)*(n/i);
}
}
printf("%lld
",res);
응용 2: 숫자 N 을 드 리 겠 습 니 다. 1 ~ N 사이 에 x 를 찾 아 gcd (x, N) > = M 을 만족 시 킬 수 있 도록 gcd (x, N) 의 합 을 찾 을 수 있 습 니 다. 분석: 이 문 제 는 gcd (X, N) 의 합 을 요구 합 니 다. 지난 문 제 는 문제 의 뜻 을 만족 시 키 는 개 수 를 구 했 기 때문에 지난 응용 을 바탕 으로 최대 공약수 만 곱 하면 최종 답 입 니 다.
LL res=0,i;
for(i=1;i*i<=n;i++)
{
if(n%i==0)
{
if(i>=m)
res+=euler(n/i)*i;
if(i*i!=n&&n/i>=m)
res+=euler(i)*(n/i);
}
}
printf("%lld
",res);
응용 3: 1 ~ N 사이 에 x 를 찾 아 gcd (x, N) > = M 을 만족 시 킬 수 있 도록 숫자 N 을 드 립 니 다. 분석: 이 문 제 는 앞의 두 문제 와 대체적으로 같 습 니 다. 최대 공약수 d 를 매 거 할 때 gcd (X, N) = d 의 모든 X 의 합 을 구하 면 됩 니 다.위 에서 알 수 있 듯 이 조건 을 만족 시 키 는 X 개 수 는 euler (N / d) 개가 있 기 때문에 N / d 를 초과 하지 않 고 N / d 와 서로 소 화 된 수의 합 을 구하 고 d 를 곱 하면 최대 공약수 가 d 일 때 대응 하 는 부분 적 인 결과 이다.N / d 를 초과 하지 않 고 N / d 와 호 환 되 는 수의 합 = N / d * euler (N / d) / 2 를 초과 하지 않 습 니 다. N / d = 1 일 때 결 과 는 0 이 아 닌 1 입 니 다.이런 것들 을 이해 하면 이 문 제 를 해결 할 수 있다.1, 2 를 제외 하고 모든 수의 오로라 함 수 는 짝수 이다.만약 k < = n 그리고 (k, n) = 1, 그러면 (n - k, n) = 1;
#include
#include
#include
#include
#include
using namespace std;
#define M 1000000007
typedef long long LL;
LL euler(LL n)
{
LL ans=n,i;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0)
n/=i;
}
}
if(n>1)
ans=ans/n*(n-1);
return ans;
}
LL euler_sum(LL n)
{
if(n==1)
return 1;
return n*(euler(n))/2;
}
int main()
{
int t;
LL n,m;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&n,&m);
LL res=0,i;
for(i=1;i*i<=n;i++)
{
if(n%i==0)
{
if(i>=m)
{
res+=euler_sum(n/i)*i;
res%=M;
}
if(i*i!=n&&n/i>=m)
{
res+=euler_sum(i)*(n/i);
res%=M;
}
}
}
printf("%lld
",res);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
NYOJ 5 바 이 너 리 문자열 매 칭 (데이터 구조)Binary String Matching 시간 제한: 3000 ms | 메모리 제한: 65535 KB 난이도: 묘사 하 다. Given two strings A and B, whose alphabet consis...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.