51nod 1643

版权声明:原来这里可以拿来卖萌ヽ(・∀・)ノ https://blog.csdn.net/u012345506/article/details/81603385

花了两天磨磨蹭蹭把这题a了。。

显然的, f ( n ) = i | n i ϕ ( n i ) ,因为 ϕ 是一个积性函数,故 f 也是一个积性函数, g ( n ) 也是一个积性函数。

先计算 f ( p n ) 的值:
f ( p n ) = i | p n i ϕ ( p n i )
= i = 0 n p i ( p n i p n i 1 )
= n ( p n p n 1 ) + p n

再计算 g ( p n ) 的值:
g ( p n ) = 1 + i = 1 n f ( p i )
= i = 0 n p i + i = 1 n i ( p i p i 1 )
= i = 0 n p i + ( 1 + p 2 p + 2 p 2 3 p 2 + 3 p 3 . . . + n p n )
= i = 0 n p i i = 0 n 1 p i + n p n
= ( n + 1 ) p n

回到问题,注意到 c 的范围只有 10 7 x i 的循环节长度必然不会超过 c 的范围。故先处理出循环节内的所有数,并计算出循环节的长度、循环节前面多余部分的长度以及在最后一个循环节中剩余部分的长度,并以此处理出每个数的出现次数。

z ( i ) 表示 i 的出现次数,我们从大到小计算,设 p i 的最小素因子,那么:
z ( p ) = z ( p ) + z ( i ) ,我们将 i 产生的 p 计数;
z ( i p ) = z ( i p ) + z ( i ) ,剩下的我们弄到 i p 处理。

因为 z 可能会爆longlong,所以我维护了模 10 9 + 7 z 和模 10 9 + 6 z 。。

以此我们可以在 O ( c ) 下计算出所有素数的出现次数,最后逐个计算即可。
时间复杂度 O ( c + 64 c l o g c ) ?(乱算的)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
//Container--
#include<unordered_map>
#include<map>
//
#define clr(a) memset(a,0,sizeof(a))
typedef long long ll;const ll md=1e9+7;const int up=1e7,sup=670000;
int mi[up+10],pn,pr[sup],cq[up+10][2];ll m;int da,db,dc,x1;

inline ll qni(ll a,ll b){
    ll r=1;for(;b;b>>=1,a=a*a%md)if(b&1)r=r*a%md;return r;
};

void init(){
    int i,j,k,d,t;for(pn=0,i=2;i<=up;++i){
        if(!cq[i][0]){pr[pn++]=i;mi[i]=i;}
        for(j=0;j<pn&&(ll)pr[j]*i<=up;++j){
            mi[pr[j]*i]=pr[j],cq[pr[j]*i][0]=1;
            if(!(i%pr[j]))break;
        }
    }
    clr(cq);
};

ll _cl(int p,ll x,ll dx){
    ll z=qni(p,x);
    return (dx+1)*z%md;
};

void cl(){
    scanf("%lld %d %d %d %d",&m,&x1,&da,&db,&dc);
    int i,j,k,d,t,lq,lm,lr;
    for(init(),lm=0,i=x1;;i=((ll)i*da+db)%dc+1){
        if(cq[i][0]){
            lm=lm-cq[i][0]+1;
            lq=cq[i][0]-1;
            break;
        }
        cq[i][0]=++lm;
    }
    lr=m<=lq?0:((m-lq)%lm);
    for(i=2;i<=up;++i)if(cq[i][0]){
        if(cq[i][0]<=lq)cq[i][0]=cq[i][1]=1;
        else{
            if(m<=lq)cq[i][0]=cq[i][1]=0;
            else{
                if(cq[i][0]-lq<=lr)cq[i][0]=((m-lq)/lm+1)%(md-1),cq[i][1]=((m-lq)/lm+1)%md;
                else
                    cq[i][0]=(m-lq)/lm%(md-1),cq[i][1]=(m-lq)/lm%md;
            }
        }
    }
    for(i=up;i>1;--i)if(mi[i]!=i){
        cq[mi[i]][0]=((ll)cq[mi[i]][0]+cq[i][0])%(md-1);
        cq[mi[i]][1]=((ll)cq[mi[i]][1]+cq[i][1])%md;
        cq[i/mi[i]][0]=((ll)cq[i/mi[i]][0]+cq[i][0])%(md-1);
        cq[i/mi[i]][1]=((ll)cq[i/mi[i]][1]+cq[i][1])%md;
    }
    ll rs=1;for(i=0;i<pn;++i)rs=rs*_cl(pr[i],cq[pr[i]][0],cq[pr[i]][1])%md;
    printf("%lld\n",rs);
};

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif
    cl();
    return 0;
};

猜你喜欢

转载自blog.csdn.net/u012345506/article/details/81603385
今日推荐