The 2019 ICPC Asia Yinchuan Regional Programming Contest/2019銀川區域賽 D Easy Problem(莫比烏斯反演+歐拉降冪)

題意

給你n,m,d,kn,m,d,k計算下列式子
i1=1mi2=1mi3=1min=1m[gcd(i1,i2,i3,,in)==d](i1i2i3in)k\sum_{i_1=1}^m\sum_{i_2=1}^m\sum_{i_3=1}^m\cdots\sum_{i_n=1}^m[gcd(i_1,i_2,i_3,\cdots,i_n)==d](i_1i_2i_3\cdots i_n)^k
其中1n10100000,1m,d100000,1k1091\le n\le 10^{100000},1\le m,d\le100000,1\le k\le10^9

思路

先提出一個dd
i1=1mdi2=1mdi3=1mdin=1md[gcd(i1,i2,i3,,in)==1]dkn(i1i2i3in)k\sum_{i_1=1}^{\frac{m}{d}}\sum_{i_2=1}^{\frac{m}{d}}\sum_{i_3=1}^{\frac{m}{d}}\cdots\sum_{i_n=1}^{\frac{m}{d}}[gcd(i_1,i_2,i_3,\cdots,i_n)==1]d^{kn}(i_1i_2i_3\cdots i_n)^k
dkni1=1mdi2=1mdi3=1mdin=1md[gcd(i1,i2,i3,,in)==1](i1i2i3in)kd^{kn}\sum_{i_1=1}^{\frac{m}{d}}\sum_{i_2=1}^{\frac{m}{d}}\sum_{i_3=1}^{\frac{m}{d}}\cdots\sum_{i_n=1}^{\frac{m}{d}}[gcd(i_1,i_2,i_3,\cdots,i_n)==1](i_1i_2i_3\cdots i_n)^k
再將jgcd(i1,i2,i3,,in)μ(j)=[gcd(i1,i2,i3,,in)==1]\sum_{j|gcd(i_1,i_2,i_3,\cdots,i_n)}\mu(j)=[gcd(i_1,i_2,i_3,\cdots,i_n)==1]帶入
dkni1=1mdi2=1mdi3=1mdin=1mdjgcd(i1,i2,i3,,in)μ(j)(i1i2i3in)kd^{kn}\sum_{i_1=1}^{\frac{m}{d}}\sum_{i_2=1}^{\frac{m}{d}}\sum_{i_3=1}^{\frac{m}{d}}\cdots\sum_{i_n=1}^{\frac{m}{d}}\sum_{j|gcd(i_1,i_2,i_3,\cdots,i_n)}\mu(j)(i_1i_2i_3\cdots i_n)^k
原來是枚舉gcdgcd的因子我們可以換成枚舉他的倍數
dknj=1mdμ(j)i1=1mdji2=1mdji3=1mdjin=1mdjjkn(i1i2i3in)kd^{kn}\sum_{j=1}^{\frac{m}{d}}\mu(j)\sum_{i_1=1}^{\frac{m}{dj}}\sum_{i_2=1}^{\frac{m}{dj}}\sum_{i_3=1}^{\frac{m}{dj}}\cdots\sum_{i_n=1}^{\frac{m}{dj}}j^{kn}(i_1i_2i_3\cdots i_n)^k
dknj=1mdμ(j)jkni1=1mdji2=1mdji3=1mdjin=1mdj(i1i2i3in)kd^{kn}\sum_{j=1}^{\frac{m}{d}}\mu(j)j^{kn}\sum_{i_1=1}^{\frac{m}{dj}}\sum_{i_2=1}^{\frac{m}{dj}}\sum_{i_3=1}^{\frac{m}{dj}}\cdots\sum_{i_n=1}^{\frac{m}{dj}}(i_1i_2i_3\cdots i_n)^k
乘積展開可以爲k次冪的和,只要預處理小於m的k次冪和就可以做了
dknj=1mdμ(j)jkn(1k+2k+3k++(mdj)k)nd^{kn}\sum_{j=1}^{\frac{m}{d}}\mu(j)j^{kn}(1^k+2^k+3^k+\cdots+(\frac{m}{dj})^k)^n
n比較大,用歐拉降冪

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const int mod=59964251;
const int phi=59870352;
int mu[N];
int prime[N];
int vis[N];
int cnt;
long long sum[N];
char str[N];
void init()
{
    mu[1]=1;
    for(int i=2; i<N; i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
            mu[i]=-1;
        }
        for(int j=0; j<cnt&&i*prime[j]<N; j++)
        {
            vis[prime[j]*i]=1;
            if(i%prime[j]==0)
            {
                mu[i*prime[j]]=0;
                break;
            }
            else
                mu[i*prime[j]]=-mu[i];
        }
    }
}
long long quickmod(long long a,long long b)
{
    long long ans=1;
    while(b)
    {
        if(b%2==1)
            ans=ans*a%mod;
        b=b/2;
        a=a*a%mod;
    }
    return ans;
}
int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long m,d,k;
        scanf("%s%lld%lld%lld",str,&m,&d,&k);
        m/=d;
        sum[0]=0;
        for(int i=1; i<=m; i++)
            sum[i]=(sum[i-1]+quickmod(i,k))%mod;
        int len=strlen(str);
        int flag=0;
        long long n=0;
        for(int i=0; i<len; i++)
        {
            n=n*10+str[i]-'0';
            n=n%phi;
        }
        long long ans=0;
        for(int i=1; i<=m; i++)
        {
            ans=(ans+mu[i]*quickmod(i,k*n%phi+phi)%mod*quickmod(sum[m/i],n+phi)%mod+mod)%mod;
        }
        ans=ans*quickmod(d,k*n%phi+phi)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}
/*
59870352
*/

/*
1
1000000000 100000 100000 1000000000
739066146
*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章