【HDOJ6608】Fansblog(威尔逊定理)

题意:给定质数p,求q!模p的值,其中q为小于p的最大质数

1e9<=p<=1e14

思路:根据质数密度近似分布可以暴力找q并检查

找到q后根据威尔逊定理:

 

 把q+1到p-1这一段的逆元移过去

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef unsigned int uint;
 5 typedef unsigned long long ull;
 6 typedef pair<int,int> PII;
 7 typedef pair<ll,ll> Pll;
 8 typedef vector<int> VI;
 9 #define N  110000
10 #define M  1100000
11 #define fi first
12 #define se second
13 #define MP make_pair
14 #define pi acos(-1)
15 #define mem(a,b) memset(a,b,sizeof(a))
16 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
17 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
18 #define lowbit(x) x&(-x)
19 #define Rand (rand()*(1<<16)+rand())
20 #define id(x) ((x)<=B?(x):m-n/(x)+1)
21 #define ls p<<1
22 #define rs p<<1|1
23 
24 const ll MOD=998244353,inv2=(MOD+1)/2;
25       double eps=1e-6;
26       ll INF=1e14;
27 
28 
29 int read()
30 {
31    int v=0,f=1;
32    char c=getchar();
33    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
34    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
35    return v*f;
36 }
37 
38 int prime(ll x)
39 {
40     ll t=sqrt(x);
41     for(ll i=2;i<=t;i++)
42      if(x%i==0) return 0;
43     return 1;
44 }
45 
46 ll mult(ll a,ll b,ll p)
47 {
48     ll t=(a*b-ll((long double)a/p*b+1e-3)*p)%p;
49     return t<0?t+p:t;
50 }
51 
52 ll pw(ll x,ll y,ll p)
53 {
54     ll t=1;
55     while(y)
56     {
57         if(y&1) t=mult(t,x,p);
58         x=mult(x,x,p);
59         y>>=1;
60     }
61     return t;
62 }
63 
64 int main()
65 {
66     //freopen("1.in","r",stdin);
67     //freopen("1.out","w",stdout);
68     int cas=read();
69     while(cas--)
70     {
71         ll n;
72         scanf("%I64d",&n);
73         ll k=n-2;
74         if(n==3) k=2;
75          else
76          {
77             while(k&&!prime(k)) k-=2;
78          }
79         ll ans=n-1;
80         //printf("k=%I64d\n",k);
81         for(ll i=k+1;i<=n-1;i++)
82         {
83             //printf("i=%I64d\n",i);
84             ll t=pw(i,n-2,n);
85             //printf("inv%I64d=%I64d\n",i,t);
86             ans=mult(ans,t,n);
87         }
88 
89 
90         printf("%I64d\n",ans);
91     }
92     return 0;
93 }

 

posted on 2019-09-26 19:03  myx12345  阅读(136)  评论(0编辑  收藏  举报

导航