数论 (大数,小费马定理,欧拉定理,威尔逊定理,快速数论变换(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] + "	");
 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^01(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<=10000000001<=b<=10^1000000111 注意到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)
原文地址:https://www.cnblogs.com/sylvia1111/p/11296161.html