hdu 4335 What is N? 数论

来源:互联网 发布:java断点续传上传例子 编辑:程序博客网 时间:2024/06/01 07:35


题意  给定  b,p,m  求 满足 n^(n!) %p =b  ( 0<=n<=m)  n 的个数

m  的范围 2^64 -1   这里是个trick。。。

利用降幂的公式 。    a^x %p= a^( x%phi(p) + phi(p)) %p 

就可以把指数降到 1 - p 这个范围内。

对于  kp+1   ~  (k+1)p    (k>1)这个范围中的n 可以 映射到 1 - p  这个范围。且指数必定是phi(p)  因为 x = a!  ,a>phi(p)  --->  x%phi(p) = 0;

然后对 区间暴力。。

坑爹的地方是  m = 2^64-1  p = 1 b =0  时 ,ans = 2^64  溢出 特判。。。。


#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <stack>#include <cstring>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio> #include <cstdlib>#include <ctime>#include <assert.h>#include <queue>#define REP(i,n) for(int i=0;i<n;i++)#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)#define ALLL(x) x.begin(),x.end()#define SORT(x) sort(ALLL(x))#define CLEAR(x) memset(x,0,sizeof(x))#define FILLL(x,c) memset(x,c,sizeof(x))using namespace std; const double EPS = 1e-8;#define LL  unsigned long long #define pb push_backconst int maxn = 100001;int p, b; LL m;LL phi(LL a){    LL ans = 1;    for(LL i=2;i*i<=a;i++){         if(a%i==0){                ans *= i-1;                a/=i;                while(a%i==0){                    ans *= i;                    a/= i;                }         }    }    if(a > 1){        ans*=a -1;    }    return ans;}LL fac[maxn];LL pow(LL a,LL b,LL p){    LL ret = 1;    while(b){        if(b&1){            ret *= a;            ret %= p;        }        a = a*a;        a%= p;        b= b>>1;    }    return ret;}void solve(){     LL ret = 0;     LL f= phi(p);     fac[0] =1;     for(LL i=1;i<=p;i++){                     fac[i] = fac[i-1]*i;            fac[i]%= f;     }     for(LL i=1;i<=p;i++){         if(i>m){             if(0==b)ret ++ ;             printf("%d\n",(int)ret);             return;         }         if(pow(i,fac[i]+f,p)==b){             ret ++;         }     }     LL d = (m- p)/p;     LL k = ( m - p)%p;     LL ans = 0;     for(LL i=1;i<=p;i++){          if(pow(i,f,p) == b){              if(i<=k){                  ret ++;              }              ans ++;          }     }     ret += ans*d;      if(0==b)ret ++ ;     cout << ret << endl;}int main(){    int  t;    cin >>t ;    for(int i= 1;i<=t;i++){        cin>>b>> p;        cin >> m;       // cout << m << " "<< p << " "<< b << endl;          if(m == 18446744073709551615llu && p == 1 && b == 0) {            printf("Case #%d: 18446744073709551616\n", i);        }else{           printf("Case #%d: ",i);           solve();        }            }    return 0;}



原创粉丝点击