zoukankan      html  css  js  c++  java
  • bzoj2219 数论之神

    Description

    在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神题: 对于给定的3个非负整数 A,B,K 求出满足 (1) X^A = B(mod 2*K + 1) (2) X 在范围[0, 2K] 内的X的个数!自然数论之神是可以瞬间秒杀此题的,那么你呢?

    Input

    第一行有一个正整数T,表示接下来的数据的组数( T <= 1000) 之后对于每组数据,给出了3个整数A,B,K (1 <= A, B <= 10^9, 1 <= K <= 5 * 10^8)

    Output

    输出一行,表示答案

    Sample Input

    3
    213 46290770 80175784
    3 46290770 80175784
    3333 46290770 80175784

    Sample Output

    27
    27
    297

    HINT

     新加数组一组--2015.02.27

    正解:原根,离散对数,欧拉函数,中国剩余定理,$bsgs$,$exgcd$。

    题解点击这里,我就懒得写了。。

      1 #include <bits/stdc++.h>
      2 #define il inline
      3 #define RG register
      4 #define ll long long
      5 #define r64 (2105317)
      6 #define inf (1LL<<62)
      7 
      8 using namespace std;
      9 
     10 int p[30],pr[30],num[30],st[30],a,b,x,rhl,tot,top;
     11 ll ans;
     12 
     13 il int gi(){
     14   RG int x=0,q=1; RG char ch=getchar();
     15   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     16   if (ch=='-') q=-1,ch=getchar();
     17   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     18   return q*x;
     19 }
     20 
     21 il int qpow(RG int a,RG int b,RG ll p){
     22   RG int ans=1;
     23   while (b){
     24     if (b&1) ans=1LL*ans*a%p;
     25     if (b>>=1) a=1LL*a*a%p;
     26   }
     27   return ans;
     28 }
     29 
     30 il int getg(RG int p,RG int phi){
     31   RG int x=phi; top=0;
     32   for (RG int i=2;i*i<=x;++i){
     33     if (x%i) continue;
     34     while (!(x%i)) x/=i; st[++top]=i;
     35   }
     36   if (x!=1) st[++top]=x;
     37   for (RG int g=2,i;;++g){
     38     for (i=1;i<=top;++i)
     39       if (qpow(g,phi/st[i],p)==1) break;
     40     if (i>top) return g;
     41   }
     42   return 0;
     43 }
     44 
     45 struct hash{
     46   
     47   struct edge{ int nt,to,dis; }g[100005];
     48   
     49   int head[r64+5],st[r64+5],num,top;
     50   
     51   il void init(){
     52     for (RG int i=1;i<=top;++i) head[st[i]]=0; top=num=0; return;
     53   }
     54   
     55   il void insert(RG int from,RG int to,RG int dis){
     56     g[++num]=(edge){head[from],to,dis},head[from]=num; return;
     57   }
     58   
     59   il void add(RG int x,RG int v){
     60     RG int base=x%r64;
     61     if (!head[base]) st[++top]=base; insert(base,x,v); return;
     62   }
     63   
     64   il int query(RG int x){
     65     RG int base=x%r64;
     66     for (RG int i=head[base];i;i=g[i].nt)
     67       if (g[i].to==x) return g[i].dis;
     68     return -1;
     69   }
     70   
     71 }hsh;
     72 
     73 il int bsgs(RG int a,RG int b,RG int p){
     74   RG int m=ceil(sqrt(p)); hsh.init();
     75   for (RG int i=0,t=b;i<=m;++i,t=1LL*t*a%p) hsh.add(t,i);
     76   for (RG int i=1,t=qpow(a,m,p),x=t,y;i<=m;++i,x=1LL*x*t%p)
     77     if (~(y=hsh.query(x))) return i*m-y;
     78   return -1;
     79 }
     80 
     81 il int gcd(RG int a,RG int b){ return b ? gcd(b,a%b) : a; }
     82 
     83 il void work(){
     84   a=gi(),b=gi(),rhl=gi()<<1|1,x=rhl,tot=0;
     85   for (RG int i=2;i*i<=x;++i){
     86     if (x%i) continue; p[++tot]=i,pr[tot]=1,num[tot]=0;
     87     while (!(x%i)) x/=i,pr[tot]*=i,num[tot]++;
     88   }
     89   if (x!=1) p[++tot]=x,pr[tot]=x,num[tot]=1; ans=1;
     90   for (RG int i=1;i<=tot;++i)
     91     if (!(b%pr[i])) ans=ans*qpow(p[i],num[i]-(num[i]-1)/a-1,inf); else{
     92       RG int B=b,cnt=0;
     93       while (!(B%p[i])) B/=p[i],pr[i]/=p[i],--num[i],++cnt;
     94       if (cnt%a){ ans=0; break; } RG int phi;
     95       if (pr[i]!=1) phi=pr[i]/p[i]*(p[i]-1); else phi=1;
     96       RG int g=getg(pr[i],phi),t=bsgs(g,B%pr[i],pr[i]);
     97       if (t==-1){ ans=0; break; } RG int G=gcd(a,phi);
     98       if (t%G){ ans=0; break; } ans*=G*qpow(p[i],cnt-cnt/a,inf);
     99     }
    100   printf("%lld
    ",ans); return;
    101 }
    102 
    103 int main(){
    104 #ifndef ONLINE_JUDGE
    105   freopen("god.in","r",stdin);
    106   freopen("god.out","w",stdout);
    107 #endif
    108   RG int T=gi();
    109   while (T--) work();
    110   return 0;
    111 }
  • 相关阅读:
    U1
    std::vector的内存释放
    (转)浅谈PostgreSQL的索引
    PostgreSQL的generate_series函数应用
    linux 里的`反引号
    wireshark抓取本地回环数据包
    linux shell中 if else以及大于、小于、等于逻辑表达式介绍
    c++利用互斥锁实现读写锁
    c++互斥锁的实现
    大小端,"字节序"
  • 原文地址:https://www.cnblogs.com/wfj2048/p/8317245.html
Copyright © 2011-2022 走看看