|
原根问题
[这个贴子最后由wanwna在 2009/09/03 09:10pm 第 2 次编辑]
代码如下(用C语言编写)
运行操作系统:SUSE Linux Enterprise Server 10
利用筛法筛出范围内所有质数
1~p-1在模乘下合成一Abel群,p-1是群的阶,则所有元的周期都是p-1的约数。
2的周期为p-1,称2为原根。
如果2的周期不是p-1,计为o(2)
则一定存在一个质数p2
使得p2|p-1且o(2)|(p-1)/p2
固只要把p-1因式分解,以每个不同的质数因子相除即可检验。
另外,对于2^((p-1)/p2)%p我以前介绍过幂模算法,这里求余数就是用的这种算法
代码写的很混乱,取名随意,并且没有注释,影响阅读请见谅- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #ifndef WHICH_NUMBER
- #define WHICH_NUMBER 2
- #endif
- int a[2000000]={2};
- int b[14];
- int bit_mod[32]={WHICH_NUMBER};
- int main(int argc,char**argv)
- {
- char*s;
- int c,i,j,k,m,n,x,y,p,q;
- int c_a=0;
- sscanf(argv[1],"%d",&c);
- s=malloc(c);
- for(i=3;i<=c;i++)
- s[i]=1;
- k=(int)(sqrt((double)c));
- for(j=3;j<=k;j+=2) {
- for(i=j*3;i<=c;i+=j*2)
- s[i]=0;
- }
- /******All prime numbers less than c****/
- j=1;
- for(i=3;i<=c;i+=2)
- if(s[i]==1) {
- a[j++]=i;
- }
- free(s);
- c=j;
- /*printf("j=%d\n",j);
- while(1) {
- scanf("%d",&i);
- printf("%d\n",a[i]);
- }*/
- for(i=8;i<c;i++) {
- m=a[i];
- x=n=m-1;
- for(j=1;j<=31;j++)
- bit_mod[j]=((long long)bit_mod[j-1])*((long long)bit_mod[j-1])%m;
- for(j=0;j<7;j++)b[j]=0;
- k=0;
- for(j=0;;j++) {
- if(x==1)
- break;
- while(1) {
- if(x%a[j]==0) {
- b[k]=a[j];
- x/=a[j];
- } else {
- if(b[k])
- k++;
- break;
- }
- }
- }//for(j=0;;j++)
- for(j=0;j<k;j++) {
- x=n/b[j];
- //printf("x:%d\n",x);
- y=1;
- for(p=0;p<31;p++){
- if((1<<p)&x)
- y=(long long)y*(long long)(bit_mod[p])%m;
- }
- if(y==1) {
- //printf("%s:%d\n",__FILE__,__LINE__);
- break;
- }
- } //for(j=0;j<k;j++)
- if(j<k) {
- } else {
- c_a++;
- }
- }//for(i=1;i<c;i++)
- printf("%d\t%d\t%lf\n",c_a,c-1,(double)c_a/(double)(c-1));
- return 0;
- }
复制代码 |
|