数论 (大数,小费马定理,欧拉定理,威尔逊定理,快速数论变换(NNT)模版)
Posted sylvia1111
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论 (大数,小费马定理,欧拉定理,威尔逊定理,快速数论变换(NNT)模版)相关的知识,希望对你有一定的参考价值。
1 Java大数 2 import java.util.*; 3 import java.math.*; 4 public class Main 5 public static void main(String args[]) 6 Scanner cin = new Scanner(System.in); 7 BigInteger a, b; 8 9 //以文件EOF结束 10 while (cin.hasNext()) 11 a = cin.nextBigInteger(); 12 b = cin.nextBigInteger(); 13 14 System.out.println(a.add(b)); //大整数加法 15 System.out.println(a.subtract(b)); //大整数减法 16 System.out.println(a.multiply(b)); //大整数乘法 17 System.out.println(a.divide(b)); //大整数除法(取整) 18 System.out.println(a.remainder(b)); //大整数取模 19 20 //大整数的比较 21 if( a.compareTo(b) == 0 ) System.out.println("a == b"); //大整数a==b 22 else if( a.compareTo(b) > 0 ) System.out.println("a > b"); //大整数a>b 23 else if( a.compareTo(b) < 0 ) System.out.println("a < b"); //大整数a<b 24 25 //大整数绝对值 26 System.out.println(a.abs()); //大整数a的绝对值 27 28 //大整数的幂 29 int exponent=10; 30 System.out.println(a.pow(exponent)); //大整数a的exponent次幂 31 32 //返回大整数十进制的字符串表示 33 System.out.println(a.toString()); 34 35 //返回大整数p进制的字符串表示 36 int p=8; 37 System.out.println(a.toString(p)); 38 39 40 41 42 高精度小数A+B,要去掉末尾的后导0. 43 import java.math.*; 44 import java.util.*; 45 46 public class Main 47 void solve () 48 //BigInteger a, b, c; 49 Scanner cin = new Scanner(System.in); 50 BigDecimal a = BigDecimal.valueOf (0); 51 BigDecimal b = BigDecimal.valueOf (0); 52 while (cin.hasNext ()) 53 a = cin.nextBigDecimal (); 54 b = cin.nextBigDecimal (); 55 System.out.println (a.add (b).stripTrailingZeros().toPlainString()); 56 57 58 public static void main (String[] args) 59 Main work = new Main(); 60 work.solve (); 61 62 63 64 Java二维数组 65 从控制台输入行数,打印对应的杨辉三角 66 //从控制台获取行数 67 Scanner s = new Scanner(System.in); 68 int row = s.nextInt(); 69 //根据行数定义好二维数组,由于每一行的元素个数不同,所以不定义每一行的个数 70 int[][] arr = new int[row][]; 71 //遍历二维数组 72 for(int i = 0; i < row; i++) 73 //初始化每一行的这个一维数组 74 arr[i] = new int[i + 1]; 75 //遍历这个一维数组,添加元素 76 for(int j = 0; j <= i; j++) 77 //每一列的开头和结尾元素为1,开头的时候,j=0,结尾的时候,j=i 78 if(j == 0 || j == i) 79 arr[i][j] = 1; 80 else //每一个元素是它上一行的元素和斜对角元素之和 81 arr[i][j] = arr[i -1][j] + arr[i - 1][j - 1]; 82 83 System.out.print(arr[i][j] + "\t"); 84 85 System.out.println(); 86 87 88 89 90 三个重要的同余式——威尔逊定理、费马小定理、欧拉定理 + 求幂大法 91 一、威尔逊定理 92 若p为质数,则 93 p|(p-1)!+1 94 亦:(p-1)! ≡ p-1 ≡ -1(mod p) 95 威尔逊定理的逆也成立. 96 97 二、费马小定理 98 假如p是质数,且gcd(a,p)=1,那么 99 a^(p-1) ≡1(mod p) 100 我们可以利用费马小定理来简化幂模运算:由于a^(p-1)≡a^0≡1(mod p),所以a^x(mod p)有循环节,长度为p-1,所以a^x≡a^(x%(p-1))(mod p) 101 三、欧拉定理 102 若a,m为正整数,且gcd(a,m) = 1,则 103 a^φ(m)≡1(mod m) 104 我们亦可以利用欧拉定理来简化幂模运算:a^x≡a^(x%φ(m))(mod m) 105 为下一节做铺垫,我们将a^x≡a^(x%φ(m))(mod m)变下形: 106 由于a^φ(m)≡1(mod m) 107 a^x≡a^(x%φ(m))≡a^(x%φ(m)+φ(m))(mod m) 108 109 四、求幂大法(广义欧拉定理)及其证明 110 对于同余式a^b≡x(mod m),如何求出x?(1<=a,m<=1000000000,1<=b<=10^1000000) 111 注意到b很大,我们可以先采取一些方法降幂。 112 若gcd(a,m)=1,那么使用欧拉定理即可:a^b≡a^(b%φ(m))(mod m) 113 若gcd(a,m)>1,且b>φ(m),则有“求幂大法”——a^b≡a^(b%φ(m)+φ(m))(mod m) 114 (当b<=φ(m)时直接用快速幂即可) 115 116 117 __int128_t 输入输出 118 119 void scan(__int128_t &x) 120 x = 0; 121 int f = 1; 122 char ch; 123 if((ch = getchar()) == ‘-‘) f = -f; 124 else x = x * 10 + ch - ‘0‘; 125 while((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) 126 x = x * 10 + ch - ‘0‘; 127 x *= f; 128 129 130 void _print(__int128_t x) 131 if(x<0) putchar(‘-‘), x *= -1; 132 if(x>9) _print(x / 10); 133 putchar(x%10 + ‘0‘); 134 135 136 137 __int128_t 170141183460469231731687303715884105727 1e38 138 __uint128_t 340282366920938463463374607431768211455 3e38 139 140 141 142 Python input and output 143 A + B problem 144 145 try: 146 while True: 147 a, b = map(int, input().split()) 148 print(a + b) 149 except: 150 pass 151 152 153 快速数论变换(NNT)模版 154 155 const int MAXN = 800005; 156 157 const int P=998244353; 158 const int g=3;//P的原根 159 int W[MAXN]; 160 int mod_pow(int a, int k) 161 162 ll A=1LL*a,ANS=1LL; 163 for(;k;k>>=1,A=A*A%P) 164 165 if(k&1) 166 167 ANS=ANS*A%P; 168 169 170 return (int)ANS%P; 171 172 void ntt(ll A[],int nn,int ty) 173 174 int t1,t2,i,j,k,m; 175 for(i=0;i<nn;i++) 176 177 for(j=0,k=i,m=1;m<nn;m<<=1,j=(j<<1)|(k&1),k>>=1); 178 if(i<j) 179 180 t1=A[i]; 181 A[i]=A[j]; 182 A[j]=t1; 183 184 185 W[0]=1; 186 for(m=1;m<nn;m<<=1) 187 188 t1= mod_pow(g, P - 1 + ty * (P - 1) / (m << 1)); 189 for(i=1;i<m;i++) 190 191 W[i]=1LL*W[i-1]*t1%P; 192 193 for(k=0;k<nn;k+=m<<1) 194 195 for(i=k;i<k+m;i++) 196 197 t1=A[i]; 198 t2=1LL*A[i+m]*W[i-k]%P; 199 A[i]=t1+t2; 200 A[i]-=A[i]>P?P:0; 201 A[i+m]=t1-t2; 202 A[i+m]+=A[i+m]<0?P:0; 203 204 205 206 if(ty==1) 207 208 return ; 209 210 t1= mod_pow(nn, P - 2); 211 for(i=0;i<nn;i++) 212 213 A[i]=1LL*A[i]*t1%P; 214 215 216 217 218 使用方法 219 元素个数是2的幂。 220 221 nnt变换:nnt(数组名, 元素个数, 1) 222 nnt逆变换:nnt(数组名, 元素个数, -1)
以上是关于数论 (大数,小费马定理,欧拉定理,威尔逊定理,快速数论变换(NNT)模版)的主要内容,如果未能解决你的问题,请参考以下文章