链接: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; }