HDU 多校 第三场 Fansblog

代码千万条,规范第一条

训练赛的时候打表找规律,发现答案是1/(st-pre-1)!,奈何用错了模板,一直TLE到比赛结束,一直以为是卡什么输入输出或者是两个素数相差太大导致复杂度过高,读入优化啥的都往上搞qaq,太菜了,没想到是mrt板子的锅qaq

题意:求解n!%p ,n为p前面第一个素数,p也为素数

代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int num;
#define ll long long
namespace io {
char buf[1<<21], *p1 = buf, *p2 = buf;
inline char gc() {
    if(p1 != p2) return *p1++;
    p1 = buf;
    p2 = p1 + fread(buf, 1, 1 << 21, stdin);
    return p1 == p2 ? EOF : *p1++;
}

#define G getchar

template<class I>
inline void read(I &x) {
    x = 0; I f = 1; char c = G();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = G(); }
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = G(); }
    x *= f;
}

template<class I>
inline void write(I x) {
    if(x == 0) {putchar('0'); return;}
    I tmp = x > 0 ? x : -x;
    if(x < 0) putchar('-');
    int cnt = 0;
    while(tmp > 0) {
        buf[cnt++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while(cnt > 0) putchar(buf[--cnt]);
}

#define in(x) read(x)
#define outn(x) write(x), putchar('\n')
#define out(x) write(x), putchar(' ')

} using namespace io;
const int times = 20;
ll Random(ll n)//生成[ 0 , n ]的随机数
{
    return ((double)rand()/RAND_MAX*n+0.5);
}
ll qpow(ll a, ll b, ll mod)//快速计算 (a*b) % mod
{
    ll ans=0;
    while(b)
    {
        if(b&1)
        {
            b--;
            ans=(ans+a)%mod;
        }
        b/=2;
        a=(a+a)%mod;
    }
    return ans;
}
ll q_pow(ll a,ll b,ll mod)//快速计算 (a^b) % mod
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
            ans=qpow(ans,a,mod );
        }
        b/=2;
        a=qpow(a,a,mod);
    }
    return ans;
}
bool witness(ll a,ll n)//miller_rabin算法的精华
{//用检验算子a来检验n是不是素数
    ll tem=n-1;
    int j=0;
    while(tem%2==0)
    {
        tem/=2;
        j++;
    }
    //将n-1拆分为a^r * s
    ll x=q_pow(a,tem,n); //得到a^r mod n
    if(x==1||x==n-1) return true;//余数为1则为素数
    while(j--) //否则试验条件2看是否有满足的 j
    {
        x=qpow(x,x,n);
        if(x==n-1)return true;
    }
    return false;
}
bool miller_rabin(ll n)//检验n是否是素数
{

    if(n==2)return true;
    if(n<2||n%2==0)return false;//如果是2则是素数,如果<2或者是>2的偶数则不是素数
    for(register int i=1;i<=times;i++)//做times次随机检验
    {
        ll a=Random(n-2)+1;//得到随机检验算子 a
        if(!witness(a,n))return false;//用a检验n是否是素数
    }
    return true;
}
int main()
{
    int t;
    read(t);
    while(t--)
    {
        long long int st;
        read(st);
        long long int pre=-1;
        if(st<=1e9+7)
        {
            pre=999999937;
        }
        else
        {
            for(long long  i=st-1;; i--)
            {
                //printf("%lld\n",i);
                if(miller_rabin(i))
                {
                    pre=i;
                    break;
                }
            }
        }
        //printf("%lld\n",pre);
        long long int mm=st-pre;
        long long int ans=1;
        for(long long int i=1; i<mm; i++)
        {
            ans=((ans%st)*(i%st))%st;
        }
        long long int ss=q_pow(ans,st-2,st);
        outn(ss);
    }
    return 0;
}
View Code

 

posted @ 2019-07-29 22:38  nlc_x  阅读(167)  评论(0编辑  收藏  举报