hdu6608 Fansblog(Miller_Rabin随机素数判断+威尔逊定理+费马小定理)

Farmer John keeps a website called ‘FansBlog’ .Everyday , there are many people visited this blog.One day, he find the visits has reached P , which is a prime number.He thinks it is a interesting fact.And he remembers that the visits had reached another prime number.He try to find out the largest prime number Q ( Q < P ) ,and get the answer of Q! Module P.But he is too busy to find out the answer. So he ask you for help. ( Q! is the product of all positive integers less than or equal to n: n! = n * (n-1) * (n-2) * (n-3) *… * 3 * 2 * 1 . For example, 4! = 4 * 3 * 2 * 1 = 24 )

Input

First line contains an number T(1<=T<=10) indicating the number of testcases.
Then T line follows, each contains a positive prime number P (1e9≤p≤1e14)

Output

For each testcase, output an integer representing the factorial of Q modulo P.

Sample Input

1
1000000007

Sample Output

328400734

给你一个素数p,求小于p的第一个素数q!(mod p) 

纯粹的数学题,趁此学一学 威尔逊定理 && 费马小定理 && 二次探测定理 && Miller_Rabin

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll prime[12]= {2,3,5,7,11,13,17,19,23,29,31,37};///取遍30以内的素数保证int范围内不出错,这里取到40

ll quick_multiply(ll a,ll b,ll c)///快速积  防爆long long 和快速幂差不多
{
    ll ans=0,res=a;
    while(b)
    {
        if(b&1)
            ans=(ans+res)%c;
        res=(res+res)%c;
        b>>=1;
    }
    return ans;
}

ll quick_power(ll a,ll b,ll c)///快速幂
{
    ll ans=1,res=a;
    while(b)
    {
        if(b&1)
            ans=quick_multiply(ans,res,c);
        res=quick_multiply(res,res,c);
        b>>=1;
    }
    return ans;
}

bool Mill_Rabin(ll n)///素数测试
{
    ll i,j,k;
    ll s=0,t=n-1;
    if(n==2)        ///特判
        return true;
    if(n<2||!(n&1))///特判
        return false;
    while(!(t&1))///把n分解成(2^s)*t的形式(具体见上面链接中的推导)
    {
        s++;
        t>>=1;
    }
    for(i=0; i<12&&prime[i]<n; ++i)///随机选取素数测试
    {
        ll a=prime[i];
        ll b=quick_power(a,t,n);///先算出a^t
        for(j=1; j<=s; ++j)///进行s次平方-->(a^t)^2^2^2……=a^((2^s)*t)
        {
            k=quick_multiply(b,b,n);
            if(k==1&&b!=1&&b!=(n-1))
                return false;///二次探测判断
            b=k;
        }
        if(b!=1)///费马小定理判断
            return false;
    }
    return true;
}

int main()
{
    int t;
    scanf("%d",&t);
    ll p;
    while(t--)
    {
        scanf("%lld",&p);
        ll q=n-1;
        while(!Mill_Rabin(q))///找到小于p的第一个素数
            q--;
        ll ans=1;
        for(ll i=q+1;i<p-1;i++)
            ans=quick_multiply(ans,quick_power(i,p-2,p),p);///由费马小定理推导(见下面链接)
        printf("%I64d\n",ans);
    }
    return 0;
}

详细推导

全部评论

相关推荐

不愿透露姓名的神秘牛友
06-29 17:30
找实习找着找着就要进入7月了,马上秋招也要开始了,找实习还有意义吗?
绝迹的星:有面就面, 没面上就当日薪4位数大佬免费培训, 面上了再考虑要不要实习
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务