链接:https://www.nowcoder.com/acm/contest/89/B
来源:牛客网
时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
There is a formula:
gcd(a, b) is the greatest common divisor of a and b.
Give you three integers L, R and K. Please calculate the value of the following formula:
输入描述:
The first line contains an integer T, where T is the number of test cases. T test cases follow.
For each test case, the only line contains three integers L, R and K.
• 1 ≤ T ≤ 20.
• 1≤ L ≤ R ≤1018.
• 1 ≤ K ≤ 105.
输出描述:
For each test case, output one line containing “Case #x: y”, where x is the test case number (starting
from 1) and y is the answer.
示例1
输入
2
1 5 6
10 20 8
输出
Case #1: 5
Case #2: 3
备注:
For the first case, answer = (1×5) mod 6 = 5.
For the second case, answer = (11×13×15×17×19) mod 8 = 3.
题意:
求区间[L,R]内与K互质的数的乘积对K取模后的值
由欧几里得定理gcd(a,b) = gcd(b, a%b)可知 gcd(a, k) = gcd(a+k, k) = ... = gcd(a+n*k, k) = gcd(k, a%k)
且 a*(a+k)*(a+2k)* ... *(a+(n-1)k) % k = a^n % k
得,若a与k互质,则(a+ik)均与k互质
可知每k个为一循环,每个循环内与k互质的数的乘积取模后的值均相同
所以只要判断有几个循环,然后快速幂一下,再乘上循环外的与k互质的数就得到答案了
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
typedef long long LL;
LL T,l,r,k,cas = 0;
LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}
LL qkm(LL n,LL m){
LL base = n,ans = 1;
while(m){
if(m&1) ans = (ans * base) % k;
base = (base * base) % k;
m /= 2;
}
return ans;
}
int main()
{
scanf("%lld",&T);
while(T--){
scanf("%lld%lld%lld",&l,&r,&k);
LL cnt = (r-l+1)/k, ans = 1;
for(LL i=1;i<=k;i++){
if(gcd(i,k)==1) ans = (ans * i) % k;
}
ans = qkm(ans, cnt);
for(LL i=l+cnt*k;i<=r;i++){
if(gcd(i%k,k)==1) ans = (ans * (i%k)) % k;
}
printf("Case #%lld: %lld\n",++cas,ans % k);
}
return 0;
}