http://acm.hdu.edu.cn/showproblem.php?pid=5780
BC #85 1005
思路:
首先原式化简:x?^gcd(a,b)??−1
也就是求n内,(公约数是i的对数)*x^i-1的和,其中i为n内的两两最大公约数。那么问题可以转化成先预处理出i,再求和,注意O(n*300)=1,正常情况会卡常数。必须还要优化
由于 ans=∑s[d]∗(x^?d??−1),记s[d]=最大公约数为d的对数
我们注意到求s[d] or (公约数是i的对数),也就是求n/i以内互质数的对数,显然用欧拉来做
s[d]=2*(phi[1]+phi[2]+...+phi[n/d])-1
注意到:d不同,但是n/d一样,也就是s[d]可能有多个相同,比如 10/6 10/7 10/8 10/9 10/10,所以求s[d]相同的项,我们可以用等比公式求和(快速幂+逆元 新知识)
所以我们只要找到每一段s[d]就可以 即 j=n/(n/i),j为最后一个相同s[d]的下标
1 // #pragma comment(linker, "/STACK:102c000000,102c000000") 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <sstream> 6 #include <string> 7 #include <algorithm> 8 #include <list> 9 #include <map> 10 #include <vector> 11 #include <queue> 12 #include <stack> 13 #include <cmath> 14 #include <cstdlib> 15 // #include <conio.h> 16 using namespace std; 17 #define pi acos(-1.0) 18 const int N = 1e6+10; 19 const int MOD = 1e9+7; 20 #define inf 0x7fffffff 21 typedef long long LL; 22 23 void fre() { freopen("in.txt","r",stdin);} 24 inline int read(){int x=0,f=1;char ch=getchar();while(ch>‘9‘||ch<‘0‘) {if(ch==‘-‘) f=-1;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘) { x=x*10+ch-‘0‘;ch=getchar();}return x*f;} 25 26 LL pow_m(LL x,LL n) 27 { 28 LL res=1; 29 while(n>0) 30 { 31 if(n & 1) 32 res=(res*x)%MOD; 33 x=(x*x)%MOD; 34 n >>= 1; 35 } 36 return res; 37 } 38 39 int prime[N],sphi[N]; 40 int inv[N]; 41 void e_fun(){ 42 sphi[1]=1; 43 for(int i=2;i<=N;i++){ 44 if(!sphi[i]){ 45 prime[++prime[0]]=i; 46 sphi[i]=i-1; 47 } 48 for(int j=1;j<=prime[0]&&i*prime[j]<=N;j++){ 49 if(i%prime[j]) sphi[i*prime[j]]=sphi[i]*(prime[j]-1); 50 else sphi[i*prime[j]]=sphi[i]*prime[j]; 51 } 52 } 53 for(int i=1;i<=N;i++) sphi[i]=(sphi[i-1]+sphi[i])%MOD; 54 55 //打表求逆元 56 // inv[1] = inv[0] = 1; 57 // for(int i = 2;i < N;i++) 58 // inv[i] = inv[MOD%i]*(MOD-MOD/i)%MOD; 59 } 60 61 62 void ex_gcd(LL a,LL b,LL &d,LL &x,LL &y) { 63 if (!b) { 64 d = a; 65 x = 1; 66 y = 0; 67 } 68 else { 69 ex_gcd(b, a%b, d, y, x); 70 y -= x*(a/b); 71 } 72 // return x; 73 } 74 75 LL sn(LL q,LL n){ 76 if(q==1) return n; 77 LL x,y,d; 78 ex_gcd(q-1,MOD,d,x,y); 79 return (pow_m(q,n)-1)*((x+MOD)%MOD)%MOD; 80 } 81 82 int main(){ 83 e_fun(); 84 int T; 85 T=read(); 86 while(T--){ 87 int x,n; 88 x=read(),n=read(); 89 LL ans=0; 90 for(int i=1,j;i<=n;i=j+1){ 91 j=n/(n/i); 92 LL sd=2*sphi[n/i]-1; 93 ans=(ans + sd*(pow_m(x,i)*sn(x,j-i+1)%MOD -(j-i+1))%MOD) % MOD; 94 } 95 printf("%I64d\n",ans); 96 } 97 return 0; 98 }
时间: 2024-10-13 13:53:45