/*************************************
求解x^a=b(mod c) x在[0,c-1]上解的个数模板
输入:1e9>=a,b>=1,1e9>=c>=3.
返回:调用xaeqbmodc(a,b,c),返回解的个数
复杂度: 找原根的复杂度很低,所以总的复杂度为O(c^0.5)
************************************/ typedef long long ll;
#define HASH_N 100007 struct hashnode
{
int next;
ll key;
int j;
}HashLink[ HASH_N ]; int hashpre[ HASH_N ],hashcnt; void hash_insert(ll x,ll key,int j)
{
for(int p=hashpre[x];p!=-;p=HashLink[p].next)
{
if(HashLink[p].key==key) return ;
}
HashLink[ hashcnt ].key = key;
HashLink[ hashcnt ].j = j;
HashLink[ hashcnt ].next = hashpre[x];
hashpre[x] = hashcnt++;
} int hash_get(ll key)
{
ll x=key%HASH_N;
for(int p=hashpre[x];p!=-;p=HashLink[p].next)
{
if( HashLink[p].key == key ) return HashLink[p].j;
}
return -;
} ll gcd(ll a,ll b)
{
if(b==) return a;
return gcd(b,a%b);
} //ax + by = gcd(a,b)
//传入固定值a,b.放回 d=gcd(a,b), x , y
void extendgcd(long long a,long long b,long long &d,long long &x,long long &y)
{
if(b==){d=a;x=;y=;return;}
extendgcd(b,a%b,d,y,x);
y-=x*(a/b);
} //Ax=1(mod M)
//返回x的范围是[0,M-1]
ll GetNi(ll A,ll M)
{
ll rex=,rey=;
ll td=;
extendgcd(A,M,td,rex,rey);
return (rex%M+M)%M;
} //a^b%mod 快速幂
long long Quk_Mul(long long a,long long b,long long mod)
{
long long qsum=;
while(b)
{
if(b&) qsum=(qsum*a)%mod;
b>>=;
a=(a*a)%mod;
}
return qsum;
} //测试x较小的情况,必须!
ll firsttest(ll A,ll B,ll C)
{
ll tmp=;
if(B==) return ;
for(int i=;i<;i++)
{
tmp = (tmp*A)%C;
if(tmp==B) return i;
}
return -;
} ll BabyStep(ll A,ll B,ll C,ll OC)
{
if(==A || ==C) return -;
if(C==) return ;
B = B%C;
ll ans = firsttest(A,B,C);//为了防止x比较小的时候
if(ans != -) return ans;
ll D=;
int c=;
ll d;
while( (d=gcd(A,C)) != )
{
if( B%d != ) return -;//无解的情况
B /= d;
C /= d;
D = D*A/d%C;
c++;
} //得到了 D*A^(x-c)=B (mod C) ,gcd(A,C)=1 , gcd(D,C)=1
ll D_1=GetNi(D,C);//求D的逆元
B = B*D_1%C;
//求A^x=B (mod C),然后返回x+c
ll m = ceil( sqrt(C+0.0) ); memset(hashpre,-,sizeof(hashpre));
hashcnt=;
ll hashnum=;
hash_insert(, , );
for(int i=;i<m;i++)
{
hashnum = (hashnum*A)%C;
hash_insert(hashnum%HASH_N, hashnum ,i);
} ll ol=OC;//这一步可以省略
ll mA=Quk_Mul(A, m, C);
ll ta=; ll tmpni = Quk_Mul(mA, ol-, C); for(int i=;i<m;i++,ta=ta*tmpni%C)
{
//解线性同余方程 tx=B*ta (%C) ,ta直接用费马小定理求逆元
ll tx = ta;
tx = (tx*B)%C;
int j=hash_get(tx);
if(j!=-)//找到解了
{
return i*m+j+c;
}
} return -;
} ll mypow(ll a,ll b)
{
ll sum=;
for(int i=;i<=b;i++)
sum*=a;
return sum;
} ll slove(ll a,ll b,ll c,ll p,int a1)
{
//第0种情况a==1
if(a==) return ; //第一种情况b==c
b %= c;
if(b==)
{
ll tmp = mypow(p,ceil( (double)a1/a ) );
return c/tmp;
}
ll d=gcd(b,c);
//第二种情况 gcd(b,c)!=1
if( d != )
{
return ;
} //第三种情况 gcd(b,c)==1 //第一步找出原根x0,
ll save[];
int cnt=; ll tc = mypow(p,a1-)*(p-);
for(ll i=;i*i<=tc;i++)
{
if(tc%i == )
{
save[ cnt++ ] = i;
while(tc%i==) tc/=i;
}
}
if(tc != )
{
save[ cnt++ ] = tc;
}
tc= mypow(p,a1-)*(p-);
for(int i=;i<cnt;i++)
{
save[i] = tc/save[i];
} ll x0=;
for(int i=;i<c;i++)
{
int flag=;
for(int j=;j<cnt;j++)
{
if( Quk_Mul(i, save[j], c) ==)
{
flag=;
break;
}
}
if(flag==)
{
x0=i;
break;
}
}
//找到原根x0后,然后找x0^a0 = b (mod c)
ll a0 = BabyStep(x0 , b, c,mypow(p,a1-)*(p-));
ll ord = mypow(p,a1-)*(p-);
d = gcd(a,ord);
if( a0%d != ) return ;
return d;
} ll xaeqbmodc(ll a,ll b,ll c)
{
ll ans=;
b%=c;
ll tc=c;
//然后对c进行因式分解
for(ll i=;i*i<=tc;i++)
{
if(tc%i==)
{
ll tmpyz=;
int a1=;
while(tc%i==)
{
a1++;
tmpyz *= i;
tc/=i;
}
//然后对这个因子进行处理
ans *= slove(a,b,tmpyz,i,a1);
if(ans==) break;
}
}
if(tc!=)
{
ans *= slove(a,b,tc,tc,);
}
return ans;
}

其实这就是hdu3731了,关于思路可惜不是完全自己想的,稍微瞟了一眼大神的做法,突破了自己原先思维中不敢动c的想法,然后这题就会做了。这题A了也表示数论算是入了个门了,记得XIANBIN5在大一的时候就把数论学完了,并且把这题A了,我还是差太多啊。 接下来就是计算几何了。

以下来自:http://www.cnblogs.com/dyllove98/archive/2013/08/05/3239030.html

求方程:的解个数

 

分析:设,那么上述方程解的个数就与同余方程组:的解等价。

 

设同于方程的解分别是:,那么原方程的解的个数就是

 

所以现在的关键问题是求方程:的解个数。

 

这个方程我们需要分3类讨论:

 

第一种情况:

 

对于这种情况,如果方程的某个解设为,那么一定有,可以得到,即

 

所以方程的解个数就是:,也就是

 

 

第二种情况:

这样也就是说p|B,设,本方程有解的充要条件是A|t,

那么我们设t=kA,

 

所以进一步有:,因为,这样又转化为第三种情况了。

第三种情况:

 

那么我们要求指标;求指标的话又要求原根。并且奇素数p的原根也是p^a的原根,所以说求个p的原根就好了。

且如果有解,则解的个数为(A,φ(p^a))。

 

求指标的话就是要解决A^x ≡ B (mod p^a)的问题。由于本情况保证了(p^a, B)=1,用个Baby-step-Giant-step就

能解决问题。

 

方程x^A ≡ B (mod p^a)有解,当且仅当(A,φ(p^a))|ind B。ind B表示B对于p^a的任一原根的指标。

最新文章

  1. 使用canal分析binlog(二) canal源码分析
  2. 安装wampserver遇到,无法启动此程序,丢失MSVCR110.dll
  3. redis_1(windows下的配置使用)
  4. Weblogic新增域(可以配置新端口)
  5. 请问view controller scene,该如何删除
  6. ASP.NET几种清除页面缓存的方法
  7. solr6.3 + Hbase Indexer使用MR创建索引,错误Bad return type
  8. webservice06#异常#Handler
  9. 2733:判断闰年-poj
  10. Action里面的自带的字段的含义
  11. MySQL数据库快速造大量数据
  12. 《Thinking In Java》---第四版 练习题答案
  13. Python_反射
  14. vue入门一
  15. python遍历本地文件系统 按文件大小排序
  16. VS诊断工具打开失败
  17. Beta版测试报告
  18. Oracle_SQL(5) 连接和子查询
  19. 设计模式之七:模板方法模式(Template Method)
  20. JS给HTML5页面&lt;Select&gt;&lt;/Select&gt;绑定选中项

热门文章

  1. django模板解析 循环列表中 切片和求长度
  2. python git log
  3. Sending SMS And Dialing Numbers without User Consent(Context is not needed)
  4. Oracle基础 存储过程和事务
  5. HDU4674 Trip Advisor
  6. js 判断是否包含
  7. jQuery异步框架探究2:jQuery.Deferred方法
  8. Oracle 格式化中文时间
  9. ASP.NET中的配置文件
  10. 从两张Excel表所想到的