gcd 题解

Posted sydevil

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gcd 题解相关的知识,希望对你有一定的参考价值。

gcd

Little White learned the greatest common divisor, so she plan to solve a problem: given (x, n,)
query (sum_{a=1}^nsum_{b=1}^ngcd(x^a?1,x^b?1))

Input

The first line of input is an integer T ( 1≤T≤300)
For each test case ,the single line contains two integers x and n ( 1≤x,n≤1000000)

Output

For each testcase, output a line, the answer mod 1000000007

Sample Input

5

3 1

4 2

8 7

10 5

10 8

Sample Output

2

24

2398375

111465

111134466

思路:

(ans=sum_{i=1}^n(x^i-1)sum_{j=1}^{lfloor frac{n}{i} floor}phi(j))

证明:

(a>b)

((x^a-1,x^b-1)=(x^a-x^b,x^b-1)=(x^b(x^{a-b}-1),x^b-1))

(ecause (x^b,x^b-1)=1)

( herefore (x^b(x^{a-b}-1),x^b-1)=(x^{a-b}-1,x^b-1)=(x^{a\%b-1},x^b-1)=(0,x^{(a,b)-1})=x^{(a,b)}-1)

优化:

如果用朴素,时间复杂度(O(Tn)),会(TLE)

因为(lfloor frac{n}{i} floor)只会有(2sqrt{n})个值,我们考虑整除分块和等比数列求和。

(mathfrak{Talk is cheap,show you the code.})

#pragma GCC optimize("Ofast")
#include<cstdio>
#include<algorithm>
using namespace std;
# define Type template<typename T>
# define read read1<int>()
Type inline T read1()
{
    T t=0;
    bool ty=0;
    char k;
    do k=getchar(),(k=='-')&&(ty=1);while('0'>k||k>'9');
    do t=(t<<3)+(t<<1)+(k^'0'),k=getchar();while('0'<=k&&k<='9');
    return ty?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
# define int long long
# define mod 1000000007ll
int l,r,phi[1000001],pri[1000001],s,m;
void work1(const int r=1000000)
{
    phi[1]=1;
    for(int i=1;i++^r;)
        phi[i]=i;
    for(int i=2;i<=r;++i)
    {
        if(phi[i]==i)
            pri[++pri[0]]=i,phi[i]=i-1;
        for(int j=1;j<=pri[0]&&pri[j]*i<=r;++j)
            if(i%pri[j])phi[i*pri[j]]=phi[i]*(pri[j]-1);
            else{phi[i*pri[j]]=phi[i]*pri[j];break;}
    }
    for(int i=0;i++^r;phi[i]=(phi[i]+phi[i-1])%mod);
}
int qkpow(int n,int m)
{
    if(!m)return 1;
    int t=qkpow(n,m>>1);
    t=t*t%mod;
    if(m&1)t=t*n%mod;
    return t;
}
int que(int l,int r)
{
    if(s==1)return r-l+1;
    return qkpow(s,l)*(qkpow(s,r-l+1)-1)%mod*qkpow(s-1,mod-2)%mod;
}
void work()
{
    s=read,m=read;
    int ans=0,l=0,r=1;
    while(l<m)
    {
        ans+=(que(l+1,r)-r+l)*(phi[m/r]*2-1)%mod;
        ans%=mod;
        l=r;
        if(l==m)break;
        r=m/(m/(l+1));
    }
    /*for(int i=0;i++^m;)
        ans=(ans+(a[i]-1)*(phi[m/i]*2-1))%mod;*/
    printf("%lld
",(ans+mod)%mod);
}
signed main()
{
    work1();
    for(int T=read;T--;work());
    return 0;
}
/*
(x^a-1,x^b-1)=(x^a-1,x^b-x^a)=(x^a-1,(x^(b-a)-1)*x^a)
=(x^a-1,x^(b-a)-1)=(x^a-1,x^(b%a)-1)
*/














以上是关于gcd 题解的主要内容,如果未能解决你的问题,请参考以下文章

题解 NOIP2020 T1 排水系统

FJUT3565 最大公约数之和(容斥)题解

[题解](gcd/欧拉函数)luogu_P2568_GCD

UVA 1642 MagicalGCD 题解

gcd 题解

[题解]luogu P2257 YY的GCD