• Bzoj2219 数论之神


    Time Limit: 3 Sec  Memory Limit: 259 MB
    Submit: 954  Solved: 268

    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

    Source

    数学问题  原根 阶 指标 中国剩余定理 脑洞题

    吼题

    学姐的讲解很棒棒 http://blog.csdn.net/regina8023/article/details/44863519

    模数$P=2*K+1$很大,在这个范围下没什么方法可以有效计算,所以需要优化数据范围。

    将P分解质因数,$p_{1}^{a1}+p_{2}^{a2}+p_{3}^{a3}+...$

    分别在每个模$ p_{i}^{ai} $ 的意义下计算出答案,将这些答案累乘起来就是最终的答案。(在每个模意义下选出一个解,则构成了一组同余方程,根据中国剩余定理,每组同余方程对应一个唯一解,所以可以用乘法原理统计总答案数)

    假设当前我们在处理一个$p^a$

    现在需要求$x^a equiv b (mod  p^a)$的解个数

    分三类情况讨论:

    如果$ gcd(p^a,b)==b $,则x是p的某次幂的形式,直接出解

    如果$ gcd(p^a,b)==1 $,问题转化为求$A*indx equiv indb (mod p^a)$的解的个数 (ind是指标)

    根据扩展欧几里得的推论,若$indb \% gcd(A,phi(p^a)) == 0 $,解的个数为 gcd(A,phi(p^a))

    如果$ gcd(p^a,b)>1 $,可以通过放缩范围转化成第二类情况。

    求逆元时候要注意模数不一定是质数,所以要用欧拉定理来求。

      没意识到这个,直接算p-2次幂,WA得飞起。

    吐槽一下数据真的弱,我求原根的时候x%pri==0写成x%pri==1,居然过了样例和discuss的hack

    隔壁yhx注释掉BSGS直接交发现A了,也就是说数据其实保证有解,根本不用判0……

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<map>
      7 #define LL long long
      8 using namespace std;
      9 const int mxn=100010;
     10 int read(){
     11     int x=0,f=1;char ch=getchar();
     12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     14     return x*f;
     15 }
     16 LL ksm(LL a,LL k){
     17     LL res=1;
     18     while(k){
     19         if(k&1)res=res*a;
     20         a=a*a;
     21         k>>=1;
     22     }
     23     return res;
     24 }
     25 LL ksm(LL a,LL k,int p){
     26     LL res=1;a%=p;
     27     while(k){
     28         if(k&1)res=(LL)res*a%p;
     29         a=(LL)a*a%p;
     30         k>>=1;
     31     }
     32     return res;
     33 }
     34 int gcd(int a,int b){return (!b)?a:gcd(b,a%b);}
     35 int exgcd(int a,int b,LL &x,LL &y){
     36     if(!b){ x=1;y=0;return a;}
     37     int tmp=exgcd(b,a%b,x,y);
     38     int c=x;x=y;y=c-a/b*x;
     39     return tmp;
     40 }
     41 //
     42 int P;
     43 int pri[mxn],cnt=0;
     44 int GetG(int p){//求原根
     45     int tmp=p-1;
     46     int m=sqrt(tmp+0.5);
     47     cnt=0;
     48     for(int i=2;i<=m;i++)
     49         if(tmp%i==0){
     50             while(tmp%i==0)tmp/=i;
     51             pri[++cnt]=i;
     52         }
     53     if(tmp>1)pri[++cnt]=tmp;
     54     for(int g=2;g<p;g++){
     55         bool is=1;
     56         for(int i=1;i<=cnt;i++)
     57             if(ksm(g,(p-1)/pri[i],p)==1){is=0;break;}
     58         if(is)return g;
     59     }
     60     return 0;
     61 }
     62 map<int,int>mp;
     63 int BSGS(int a,int b,int p,int pp){
     64     mp.clear();
     65     int m=sqrt(p),i,j;
     66     int tmp=1;
     67     for(i=1;i<=m;i++){
     68         tmp=(LL)tmp*a%p;
     69         if(tmp==b)return i;
     70         if(!mp[tmp])mp[tmp]=i;
     71     }
     72     mp[1]=0;
     73     int res=1,phi;
     74     if(pp==p)phi=p-1;
     75     else phi=p/pp*(pp-1);
     76     for(i=0;i<=p;i+=m){
     77         LL inv=ksm(res,phi-1,p);
     78         inv=inv*b%p;
     79         if(mp[inv])return mp[inv]+i;
     80         res=(LL)res*tmp%p;
     81     }
     82     return 0;
     83 }
     84 int G,A,B,K;
     85 int solve(int p,int t){//p^t
     86     int pr=ksm(p,t),b=B;
     87     b%=pr;
     88     if(!b)return ksm(p,t-((t-1)/A+1));
     89     int c=0;
     90     while(b%p==0)b/=p,c++;
     91     if(c%A)return 0;//无解
     92     //
     93     int tmp=c/A;
     94     t-=c;
     95     int phi=pr-pr/p;
     96     G=GetG(p);
     97     int ind=BSGS(G,b,pr,p);
     98     int d=gcd(A,phi);
     99     if(ind%d)return 0;
    100     return d*ksm(p,(A-1)*tmp);
    101 }
    102 int main(){
    103     int i,j;
    104     int T=read();
    105     while(T--){
    106         A=read();B=read();K=read();
    107         P=2*K+1;K=P;
    108         int m=sqrt(P),c;
    109         int ans=1;
    110         for(i=2;i<=m;i++){
    111             if(!ans)break;
    112             if(K%i==0){
    113                 c=0;
    114                 while(K%i==0)K/=i,c++;
    115                 ans*=solve(i,c);
    116             }
    117         }
    118         if(ans && K>1)ans*=solve(K,1);
    119         printf("%d
    ",ans);
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    EasyUI:Easyui parser的用法
    解决ajax 遇到session失效后自动跳转的问题
    PHP 解决同一个IP不同端口号session冲突的问题
    Linux 使用crontab定时备份Mysql数据库
    Easyui validatebox后台服务端验证
    window之间、iframe之间的JS通信
    Nginx和Apache服务器上配置反向代理
    Linux下安装并配置SSH服务
    Mac下载Navicat premium提示文件损坏的解决方案
    优酷项目整体架构
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6804361.html
Copyright © 2020-2023  润新知