00001
00002
00003
00004
00005
00006
00007
00008 #ifndef SYNAPS_ARITHM_MODP_H
00009 #define SYNAPS_ARITHM_MODP_H
00010
00011 #include <iostream>
00012 #include <cstdlib>
00013 #include <cassert>
00014 #include <synaps/init.h>
00015
00018 __BEGIN_NAMESPACE_SYNAPS
00019
00020 template <class T=int>
00021 struct ModP
00022 {
00023 private:
00024 T p;
00025
00026 public:
00027 ModP(): p(0) {}
00028 ModP(int n): p(n){ assert(n>0); };
00029 ModP(const ModP<T> & z): p(z.p) {}
00030
00031
00032 bool equal (T a, T b) {return (a-b)%p==0;}
00033 void assign(T & r, T a) {r =a %p;}
00034 void add (T & r, T a) {r+=a %p;}
00035 void add (T & r, T a, T b) {r=(a+b) %p;}
00036 void sub (T & r, T a) {r-=a %p;}
00037 void sub (T & r, T a, T b) {r=(a-b) %p;}
00038 void neg (T & r, T a) {r=-a;}
00039 void mul (T & r, T a) {r*=a; r%=p;}
00040 void mul (T & r, T a, T b) {r=(a*b) %p;}
00041 void div (T & res, T z)
00042 {
00043 assert(z!=0 && p!=0);
00044 T a=p, b=z;
00045 b %=p; b +=p; b%=p;
00046 T r=b, u1=1,u2=0, q, inv=0;
00047 while(r!=0)
00048 {
00049 q = a/b;
00050 r = (a-q*b)%p; a=b; b=r;
00051 u2= (inv-q*u1)%p; inv=u1; u1=u2;
00052 }
00053 inv+=p; inv%=p;
00054 mul(res,inv);
00055 }
00056 void div (T & r, T a, T b) {r=a; div(r,b);}
00057
00058 void print (std::ostream & os, const T & a) {os<<a;}
00059 void read (std::istream & is, T& a) {is>>a;}
00060 };
00061
00062
00063 __END_NAMESPACE_SYNAPS
00064
00065 #endif // SYNAPS_ARITHM_MODP_H