hdu 4335 What is N?

来源:互联网 发布:制作相片的软件 编辑:程序博客网 时间:2024/06/05 00:22

题目:4335

思路:对n!分成三部分,小于euler(mod)的部分,剩下的,根据能否整除euler(mod),分成循环节部分和剩余的部分(暴力)


参考了这里, here


#include <cstdio>#include <iostream>#include <cmath>#include <algorithm>#include <cstring>#include <map>using namespace std;typedef unsigned __int64 LL;LL mod,b,M;LL euler(LL x){    LL i,res=x;    for(int i=2;i*i<=x;i++)        if(x%i==0)        {            res=res/i*(i-1);            while(x%i==0)                x/=i;        }    if(x>1)        res=res/x*(x-1);    return res;}LL Pow(LL a,LL b){    LL ans=1;    while(b)    {        if(b&1)        {            b--;            ans=(ans*a)%mod;        }        else        {            b/=2;            a=(a*a)%mod;        }    }    return ans;}int main(){    int t;    cin>>t;    for(int cases=1;cases<=t;cases++)    {        cin>>b>>mod>>M;        cout<<"Case #"<<cases<<": ";        LL eul=euler(mod);        if(mod==1)        {            if(b==0)            {                if(M==18446744073709551615LLU)                    cout<<"18446744073709551616"<<endl;                else                    cout<<M+1<<endl;            }            else                cout<<0<<endl;        }        else        {            LL cnt=1,pnt=0;            LL ans=0;            LL fac=1;            for(pnt=0;pnt<=M;pnt++)            {                if(fac>=eul)                    break;                if(Pow(pnt,fac)==b)                    ans++;                fac*=pnt+1;            }            fac%=eul;            for(;pnt<=M;pnt++)            {                if(fac==0)                    break;                if(Pow(pnt,fac+eul)==b)                    ans++;                fac=fac*(pnt+1)%eul;            }            if(pnt<=M)            {                LL tmp=0;                for(LL i=0;i<mod;i++)                    if(Pow(pnt+i,eul)==b)                        tmp++;                LL miao=(M-pnt+1)/mod;                ans+=miao*tmp;                miao=(M-pnt+1)-miao*mod;                for(LL i=0;i<miao;i++)                    if(Pow(pnt+i,eul)==b)                        ans++;            }            cout<<ans<<endl;        }    }    return 0;}


原创粉丝点击