• bzoj 1951


    这道题告诉了我们一个很重要的道理:看到题,先想明白再动手!

    题意:求对999911659取模的值

    首先,由于n的数据范围不是很大(至少不是很大),所以可以O()枚举所有约数分别求组合数

    但是有个问题:根据费马小定理,

    所以组合数应当对p-1取模!

    可是p-1并不是一个质数啊

    所以我们要将p-1质因子分解,发现可以分解成四个质数之积,那么我们用四次卢卡斯定理分别计算出四个结果再用中国剩余定理合并即可。

    但我真正想说的是,如果做过礼物的话,很容易误以为这题要用拓展卢卡斯定理,然后写到死...

    所以千万不要像我一样...

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #define mode 999911659
    #define mo 999911658
    #define ll long long
    using namespace std;
    ll inv[40000][5];
    ll mul[40000][5];
    ll mod[5]={0,2,3,4679,35617};
    ll a[5];
    ll n,g;
    ll pow_mul(ll x,ll y)
    {
        ll ans=1;
        while(y)
        {
            if(y%2)
            {
                ans*=x;
                ans%=mode;
            }   
            x*=x;
            x%=mode;
            y/=2;
        }
        return ans;
    }
    void init()
    {
        for(int i=1;i<=4;i++)
        {
            inv[0][i]=inv[1][i]=mul[0][i]=mul[1][i]=1;
            for(int j=2;j<mod[i];j++)
            {
                inv[j][i]=(mod[i]-mod[i]/j)*inv[mod[i]%j][i]%mod[i];
            }
            for(int j=2;j<mod[i];j++)
            {
                inv[j][i]=inv[j-1][i]*inv[j][i]%mod[i];
                mul[j][i]=mul[j-1][i]*j%mod[i];
            }
        }
    }
    ll C(ll x,ll y,ll num)
    {
        if(x<y)
        {
            return 0;
        }else if(x==y)
        {
            return 1;
        }else if(x<mod[num])
        {
            return mul[x][num]*inv[y][num]%mod[num]*inv[x-y][num]%mod[num];
        }else
        {
            return C(x/mod[num],y/mod[num],num)*C(x%mod[num],y%mod[num],num)%mod[num];
        }
    }
    void ex_gcd(ll a,ll b,ll &x,ll &y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return;
        }
        ex_gcd(b,a%b,x,y);
        ll t=x;
        x=y;
        y=t-(a/b)*x;
    }
    ll china()
    {
        ll M=mo;
        ll ans=0;
        for(int i=1;i<=4;i++)
        {
            ll M0=M/mod[i];
            ll x,y;
            ex_gcd(M0,mod[i],x,y);
            x=(x%mod[i]+mod[i])%mod[i];
            ans+=x*M0%mo*a[i]%mo;
        }
        return ans;
    }
    ll solve(ll x,ll y)
    {
        for(int i=1;i<=4;i++)
        {
            a[i]=C(x,y,i);
        }
        return china();
    }
    int main()
    {
        scanf("%lld%lld",&n,&g);
        init();
        ll s=0;
        for(int i=1;i*i<=n;i++)
        {
            if(n%i==0)
            {
                s+=solve(n,i);
                s%=mo;
                if(n/i!=i)
                {
                    s+=solve(n,n/i);
                }
            }
             
        }
        printf("%lld
    ",pow_mul(g,s));
        return 0;
    }
  • 相关阅读:
    python 输出所有列表元素的乘积
    shell 变量赋值运算
    shell 判断变量是否为空
    js 获取地址栏域名以及URL
    python 获取列表大于指定长度的元素
    python 判断列表字符串元素首尾字符是否相同
    python 通过列表元素值截取列表并获取长度
    python 判断两个列表是否有公共元素
    python 获取列表的键值对
    python 判断列表的包含关系
  • 原文地址:https://www.cnblogs.com/zhangleo/p/9856212.html
Copyright © 2020-2023  润新知