zoukankan      html  css  js  c++  java
  • 算法模板の数学&数论

    1、求逆元

    1 int inv(int a) {
    2     if(a == 1) return 1;
    3     return (MOD - MOD / a) * inv(MOD % a);
    4 }
    View Code

    2、线性筛法

     1 bool isPrime[MAXN];
     2 int label[MAXN], prime[MAXN];
     3 int n, total;
     4 
     5 void makePrime() {
     6     n = 100000;
     7     for(int i = 2; i <= n; ++i) {
     8         if(!label[i]) {
     9             prime[total++] = i;
    10             label[i] = total;
    11         }
    12         for(int j = 0; j < label[i]; ++j) {
    13             if(i * prime[j] > n) break;
    14             label[i * prime[j]] = j + 1;
    15         }
    16     }
    17     for(int i = 0; i < total; ++i) isPrime[prime[i]] = true;
    18 }
    View Code

    3、欧拉函数

    1 void phi_table(int n) {
    2     //for(int i = 2; i <= n; ++i) phi[i] = 0;
    3     phi[1] = 1;
    4     for(int i = 2; i <= n; ++i) if(!phi[i])
    5         for(int j = i; j <= n; j += i) {
    6             if(!phi[j]) phi[j] = j;
    7             phi[j] = phi[j] / i * (i - 1);
    8         }
    9 }
    View Code

    4、高精度类模板(减法除法的正确性未验证)

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <string>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 const int MAXN = 100010;
      9 
     10 struct bign {
     11     int len, s[MAXN];
     12 
     13     bign () {
     14         memset(s, 0, sizeof(s));
     15         len = 1;
     16     }
     17     bign (int num) { *this = num; }
     18     bign (const char *num) { *this = num; }
     19 
     20     void clear() {
     21         memset(s, 0, sizeof(s));
     22         len = 1;
     23     }
     24 
     25     bign operator = (const int num) {//数字
     26         char s[MAXN];
     27         sprintf(s, "%d", num);
     28         *this = s;
     29         return *this;
     30     }
     31     bign operator = (const char *num) {//字符串
     32         for(int i = 0; num[i] == '0'; num++) ;  //去前导0
     33         if(*num == 0) --num;
     34         len = strlen(num);
     35         for(int i = 0; i < len; ++i) s[i] = num[len-i-1] - '0';
     36         return *this;
     37     }
     38 
     39     bign operator + (const bign &b) const {
     40         bign c;
     41         c.len = 0;
     42         for(int i = 0, g = 0; g || i < max(len, b.len); ++i) {
     43             int x = g;
     44             if(i < len) x += s[i];
     45             if(i < b.len) x += b.s[i];
     46             c.s[c.len++] = x % 10;
     47             g = x / 10;
     48         }
     49         return c;
     50     }
     51 
     52     bign operator += (const bign &b) {
     53         *this = *this + b;
     54         return *this;
     55     }
     56 
     57     void clean() {
     58         while(len > 1 && !s[len-1]) len--;
     59     }
     60 
     61     bign operator * (const bign &b) {
     62         bign c;
     63         c.len = len + b.len;
     64         for(int i = 0; i < len; ++i) {
     65             for(int j = 0; j < b.len; ++j) {
     66                 c.s[i+j] += s[i] * b.s[j];
     67             }
     68         }
     69         for(int i = 0; i < c.len; ++i) {
     70             c.s[i+1] += c.s[i]/10;
     71             c.s[i] %= 10;
     72         }
     73         c.clean();
     74         return c;
     75     }
     76     bign operator *= (const bign &b) {
     77         *this = *this * b;
     78         return *this;
     79     }
     80 
     81     bign operator *= (const int &b) {//使用前要保证>len的位置都是空的
     82         for(int i = 0; i < len; ++i) s[i] *= b;
     83         for(int i = 0; i < len; ++i) {
     84             s[i + 1] += s[i] / 10;
     85             s[i] %= 10;
     86         }
     87         while(s[len]) {
     88             s[len + 1] += s[len] / 10;
     89             s[len] %= 10;
     90             ++len;
     91         }
     92         return *this;
     93     }
     94 
     95     bign operator - (const bign &b) {
     96         bign c;
     97         c.len = 0;
     98         for(int i = 0, g = 0; i < len; ++i) {
     99             int x = s[i] - g;
    100             if(i < b.len) x -= b.s[i];
    101             if(x >= 0) g = 0;
    102             else {
    103                 g = 1;
    104                 x += 10;
    105             }
    106             c.s[c.len++] = x;
    107         }
    108         c.clean();
    109         return c;
    110     }
    111     bign operator -= (const bign &b) {
    112         *this = *this - b;
    113         return *this;
    114     }
    115 
    116     bign operator / (const bign &b) {
    117         bign c, f = 0;
    118         for(int i = len - 1; i >= 0; i--) {
    119             f *= 10;
    120             f.s[0] = s[i];
    121             while(f >= b) {
    122                 f -= b;
    123                 c.s[i]++;
    124             }
    125         }
    126         c.len = len;
    127         c.clean();
    128         return c;
    129     }
    130     bign operator /= (const bign &b) {
    131         *this  = *this / b;
    132         return *this;
    133     }
    134 
    135     bign operator % (const bign &b) {
    136         bign r = *this / b;
    137         r = *this - r*b;
    138         return r;
    139     }
    140     bign operator %= (const bign &b) {
    141         *this = *this % b;
    142         return *this;
    143     }
    144 
    145     bool operator < (const bign &b) {
    146         if(len != b.len) return len < b.len;
    147         for(int i = len-1; i >= 0; i--) {
    148             if(s[i] != b.s[i]) return s[i] < b.s[i];
    149         }
    150         return false;
    151     }
    152 
    153     bool operator > (const bign &b) {
    154         if(len != b.len) return len > b.len;
    155         for(int i = len-1; i >= 0; i--) {
    156             if(s[i] != b.s[i]) return s[i] > b.s[i];
    157         }
    158         return false;
    159     }
    160 
    161     bool operator == (const bign &b) {
    162         return !(*this > b) && !(*this < b);
    163     }
    164 
    165     bool operator != (const bign &b) {
    166         return !(*this == b);
    167     }
    168 
    169     bool operator <= (const bign &b) {
    170         return *this < b || *this == b;
    171     }
    172 
    173     bool operator >= (const bign &b) {
    174         return *this > b || *this == b;
    175     }
    176 
    177     string str() const {
    178         string res = "";
    179         for(int i = 0; i < len; ++i) res = char(s[i]+'0') + res;
    180         return res;
    181     }
    182 };
    183 
    184 istream& operator >> (istream &in, bign &x) {
    185     string s;
    186     in >> s;
    187     x = s.c_str();
    188     return in;
    189 }
    190 
    191 ostream& operator << (ostream &out, const bign &x) {
    192     out << x.str();
    193     return out;
    194 }
    View Code

    5、单纯形(UVA 10498)//只能解标准形式

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cmath>
     6 using namespace std;
     7 
     8 const double EPS = 1e-10;
     9 const int MAXN = 55;
    10 const int INF = 0x3fff3fff;
    11 
    12 inline int sgn(double x) {
    13     return (x > EPS) - (x < -EPS);
    14 }
    15 
    16 double A[MAXN][MAXN];
    17 double b[MAXN], c[MAXN];
    18 int N[MAXN], B[MAXN];
    19 int n, m;
    20 double v;
    21 
    22 bool init() {
    23     N[0] = B[0] = v = 0;
    24     for(int i = 1; i <= n; ++i) N[++N[0]] = i;
    25     for(int i = 1; i <= m; ++i) B[++B[0]] = n + i;
    26     return true;
    27 }
    28 
    29 void pivot(int l, int e) {
    30     b[e] = b[l] / A[l][e];
    31     A[e][l] = 1.0 / A[l][e];
    32     for(int i = 1; i <= N[0]; ++i) {
    33         int &x = N[i];
    34         if(x != e) A[e][x] = A[l][x] / A[l][e];
    35     }
    36     for(int i = 1; i <= B[0]; ++i) {
    37         int &y = B[i];
    38         b[y] -= A[y][e] * b[e];
    39         A[y][l] = -A[y][e] * A[e][l];
    40         for(int j = 1; j <= N[0]; ++j) {
    41             int &x = N[j];
    42             if(x != e) A[y][x] -= A[e][x] * A[y][e];
    43         }
    44     }
    45     v += b[e] * c[e];
    46     c[l] = -A[e][l] * c[e];
    47     for(int i = 1; i <= N[0]; ++i) {
    48         int &x = N[i];
    49         if(x != e) c[x] -= A[e][x] * c[e];
    50     }
    51     for(int i = 1; i <= N[0]; ++i) if(N[i] == e) N[i] = l;
    52     for(int i = 1; i <= B[0]; ++i) if(B[i] == l) B[i] = e;
    53 }
    54 
    55 bool simplex() {
    56     while(true) {
    57         int e = MAXN;
    58         for(int i = 1; i <= N[0]; ++i) {
    59             int &x = N[i];
    60             if(sgn(c[x]) > 0 && x < e) e = x;
    61         }
    62         if(e == MAXN) break;
    63         double delta = -1;
    64         int l = MAXN;
    65         for(int i = 1; i <= B[0]; ++i) {
    66             int &y = B[i];
    67             if(sgn(A[y][e]) > 0) {
    68                 double tmp = b[y] / A[y][e];
    69                 if(delta == -1 || sgn(tmp - delta) < 0 || (sgn(tmp - delta) == 0 && y < l)) {
    70                     delta = tmp;
    71                     l = y;
    72                 }
    73             }
    74         }
    75         if(l == MAXN) return false;
    76         pivot(l, e);
    77     }
    78     return true;
    79 }
    80 
    81 int main() {
    82     while(scanf("%d%d", &n, &m) != EOF) {
    83         for(int i = 1; i <= n; ++i) scanf("%lf", &c[i]);
    84         for(int i = 1; i <= m; ++i) {
    85             for(int j = 1; j <= n; ++j) scanf("%lf", &A[n + i][j]);
    86             scanf("%lf", &b[n + i]);
    87         }
    88         init();
    89         simplex();
    90         printf("Nasa can spend %d taka.
    ", (int)ceil(v * m));
    91     }
    92 }
    View Code

    6、高斯消元(-1无解,0无穷解,1唯一解)

     1 int guess_eliminatioin() {
     2     int rank = 0;
     3     for(int i = 0, t = 0; i < m && t < n; ++i, ++t) {
     4         int r = i;
     5         for(int j = i + 1; j < m; ++j)
     6             if(mat[r][t].val < mat[j][t].val) r = j;
     7         if(mat[r][t].isZero()) { --i; continue;}
     8         else ++rank;
     9         if(r != i) for(int j = 0; j <= n; ++j) swap(mat[i][j], mat[r][j]);
    10         for(int j = n; j >= t; --j)
    11             for(int k = i + 1; k < m; ++k) mat[k][j] -= mat[i][j] * mat[k][t] / mat[i][t];
    12     }
    13     for(int i = rank; i < m; ++i)
    14         if(!mat[i][n].isZero()) return -1;
    15     if(rank < n) return 0;
    16     for(int i = n - 1; i >= 0; --i) {
    17         for(int j = i + 1; j < n; ++j)
    18             mat[i][n] -= mat[j][n] * mat[i][j];
    19         mat[i][n] = mat[i][n] / mat[i][i];
    20     }
    21     return 1;
    22 }
    View Code

    7、离散对数(小步大步算法)(POJ 3243)

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cmath>
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 const int SIZEH = 65537;
    10 
    11 struct hash_map {
    12     int head[SIZEH], size;
    13     int next[SIZEH];
    14     LL state[SIZEH], val[SIZEH];
    15 
    16     void init() {
    17         memset(head, -1, sizeof(head));
    18         size = 0;
    19     }
    20 
    21     void insert(LL st, LL sv) {
    22         LL h = st % SIZEH;
    23         for(int p = head[h]; ~p; p = next[p])
    24             if(state[p] == st) return ;
    25         state[size] = st; val[size] = sv;
    26         next[size] = head[h]; head[h] = size++;
    27     }
    28 
    29     LL find(LL st) {
    30         LL h = st % SIZEH;
    31         for(int p = head[h]; ~p; p = next[p])
    32             if(state[p] == st) return val[p];
    33         return -1;
    34     }
    35 } hashmap;
    36 
    37 void exgcd(LL a, LL b, LL &x, LL &y) {
    38     if(!b) x = 1, y = 0;
    39     else {
    40         exgcd(b, a % b, y, x);
    41         y -= x * (a / b);
    42     }
    43 }
    44 
    45 LL inv(LL a, LL n) {
    46     LL x, y;
    47     exgcd(a, n, x, y);
    48     return (x + n) % n;
    49 }
    50 
    51 LL pow_mod(LL x, LL p, LL n) {
    52     LL ret = 1;
    53     while(p) {
    54         if(p & 1) ret = (ret * x) % n;
    55         x = (x * x) % n;
    56         p >>= 1;
    57     }
    58     return ret;
    59 }
    60 
    61 LL BabyStep_GiantStep(LL a, LL b, LL n) {
    62     for(LL i = 0, e = 1; i <= 64; ++i) {
    63         if(e == b) return i;
    64         e = (e * a) % n;
    65     }
    66     LL k = 1, cnt = 0;
    67     while(true) {
    68         LL t = __gcd(a, n);
    69         if(t == 1) break;
    70         if(b % t != 0) return -1;
    71         n /= t; b /= t; k = (k * a / t) % n;
    72         ++cnt;
    73     }
    74     hashmap.init();
    75     hashmap.insert(1, 0);
    76     LL e = 1, m = LL(ceil(sqrt(n + 0.5)));
    77     for(int i = 1; i < m; ++i) {
    78         e = (e * a) % n;
    79         hashmap.insert(e, i);
    80     }
    81     LL p = inv(pow_mod(a, m, n), n), v = inv(k, n);
    82     for(int i = 0; i < m; ++i) {
    83         LL t = hashmap.find((b * v) % n);
    84         if(t != -1) return i * m + t + cnt;
    85         v = (v * p) % n;
    86     }
    87     return -1;
    88 }
    89 
    90 int main() {
    91     LL x, z, k;
    92     while(cin>>x>>z>>k) {
    93         if(x == 0 && z == 0 && k == 0) break;
    94         LL ans = BabyStep_GiantStep(x % z, k % z, z);
    95         if(ans == -1) puts("No Solution");
    96         else cout<<ans<<endl;
    97     }
    98 }
    View Code

    8、母函数

     1 /*
     2 G(x) = 1 + x + x^2 + x^3 + …… = 1 / (1 - x)
     3 G(x) = 1 + 2x + 3x^2 + 4x^3 + …… = 1 / (1 - x)^2
     4 
     5 指数型母函数
     6 G(x) = 1 + x + x^2 / 2! + x^3 / 3! + x^4 / 4! + …… = e^x
     7 <1, -1, 1, -1, 1, -1, ……> = e^(-x)
     8 <0, 1, 0, 1, 0, 1, ……> = (e^x - e^(-x)) / 2
     9 <1, 0, 1, 0, 1, 0, ……> = (e^x + e^(-x)) / 2
    10 */
    View Code

    9、插头DP(URAL1519 括号表示法)

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <cstdio>
      5 using namespace std;
      6 typedef long long LL;
      7 
      8 const int MAXH = 20010;
      9 const int SIZEH = 13131;
     10 
     11 struct hash_map {
     12     int head[SIZEH];
     13     int next[MAXH], state[MAXH];
     14     LL value[MAXH];
     15     int size;
     16 
     17     void init() {
     18         memset(head, -1, sizeof(head));
     19         size = 0;
     20     }
     21 
     22     void insert(int st, LL tv) {
     23         int h = st % SIZEH;
     24         for(int i = head[h]; ~i; i = next[i]) {
     25             if(state[i] == st) {
     26                 value[i] += tv;
     27                 return ;
     28             }
     29         }
     30         value[size] = tv; state[size] = st;
     31         next[size] = head[h]; head[h] = size++;
     32     }
     33 } hashmap[2];
     34 
     35 hash_map *cur, *last;
     36 int acc[] = {0, -1, 1, 0};
     37 
     38 int n, m, en, em;
     39 char mat[14][14];
     40 
     41 int getB(int state, int i) {
     42     i <<= 1;
     43     return (state >> i) & 3;
     44 }
     45 
     46 int getLB(int state, int i) {
     47     int ret = i, cnt = 1;
     48     while(cnt) cnt += acc[getB(state, --ret)];
     49     return ret;
     50 }
     51 
     52 int getRB(int state, int i) {
     53     int ret = i, cnt = -1;
     54     while(cnt) cnt += acc[getB(state, ++ret)];
     55     return ret;
     56 }
     57 
     58 void setB(int &state, int i, int tv) {
     59     i <<= 1;
     60     state = (state & ~(3 << i)) | (tv << i);
     61 }
     62 
     63 void update(int x, int y, int state, LL tv) {
     64     int left = getB(state, y);
     65     int up = getB(state, y + 1);
     66     if(mat[x][y] == '*') {
     67         if(left == 0 && up == 0) cur->insert(state, tv);
     68         return ;
     69     }
     70     if(left == 0 && up == 0) {
     71         if(x == n - 1 || y == m - 1) return ;
     72         int newState = state;
     73         setB(newState, y, 1);
     74         setB(newState, y + 1, 2);
     75         cur->insert(newState, tv);
     76     } else if(left == 0 || up == 0) {
     77         if(x < n - 1) {
     78             int newState = state;
     79             setB(newState, y, up + left);
     80             setB(newState, y + 1, 0);
     81             cur->insert(newState, tv);
     82         }
     83         if(y < m - 1) {
     84             int newState = state;
     85             setB(newState, y, 0);
     86             setB(newState, y + 1, up + left);
     87             cur->insert(newState, tv);
     88         }
     89     } else {
     90         int newState = state;
     91         setB(newState, y, 0);
     92         setB(newState, y + 1, 0);
     93         if(left == 1 && up == 1) setB(newState, getRB(state, y + 1), 1);
     94         if(left == 1 && up == 2 && !(x == en && y == em)) return ;
     95         if(left == 2 && up == 2) setB(newState, getLB(state, y), 2);
     96         cur->insert(newState, tv);
     97     }
     98 }
     99 
    100 void findend() {
    101     for(en = n - 1; en >= 0; --en)
    102         for(em = m - 1; em >= 0; --em) if(mat[en][em] == '.') return ;
    103 }
    104 
    105 LL solve() {
    106     findend();
    107     cur = hashmap, last = hashmap + 1;
    108     last->init();
    109     last->insert(0, 1);
    110     for(int i = 0; i < n; ++i) {
    111         int sz = last->size;
    112         for(int k = 0; k < sz; ++k) last->state[k] <<= 2;
    113         for(int j = 0; j < m; ++j) {
    114             cur->init();
    115             sz = last->size;
    116             for(int k = 0; k < sz; ++k)
    117                 update(i, j, last->state[k], last->value[k]);
    118             swap(cur, last);
    119         }
    120     }
    121     return last->size ? last->value[0] : 0;
    122 }
    123 
    124 int main() {
    125     scanf("%d%d", &n, &m);
    126     for(int i = 0; i < n; ++i) scanf("%s", mat[i]);
    127     cout<<solve()<<endl;
    128 }
    View Code

    10、快速傅里叶变换(HDU1402)

     1 #include <cmath>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <iostream>
     5 #include <cstring>
     6 #include <complex>
     7 using namespace std;
     8 typedef complex<double> Complex;
     9 const double PI = acos(-1);
    10 
    11 void fft_prepare(int maxn, Complex *&e) {
    12     e = new Complex[2 * maxn - 1];
    13     e += maxn - 1;
    14     e[0] = 1;
    15     for (int i = 1; i < maxn; i <<= 1)
    16         e[i] = Complex(cos(2 * PI * i / maxn), sin(2 * PI * i / maxn));
    17     for (int i = 3; i < maxn; i++)
    18         if ((i & -i) != i) e[i] = e[i - (i & -i)] * e[i & -i];
    19     for (int i = 1; i < maxn; i++) e[-i] = e[maxn - i];
    20 }
    21 /* f = 1: dft; f = -1: idft */
    22 void dft(Complex *a, int N, int f, Complex *e, int maxn) {
    23     int d = maxn / N * f;
    24     Complex x;
    25     for (int n = N, m; m = n / 2, m >= 1; n = m, d *= 2)
    26         for (int i = 0; i < m; i++)
    27             for (int j = i; j < N; j += n)
    28                 x = a[j] - a[j + m], a[j] += a[j + m], a[j + m] = x * e[d * i];
    29     for (int i = 0, j = 1; j < N - 1; j++) {
    30         for (int k = N / 2; k > (i ^= k); k /= 2);
    31         if (j < i) swap(a[i], a[j]);
    32     }
    33 }
    34 
    35 const int MAXN = 131072;
    36 Complex x1[MAXN], x2[MAXN];
    37 char s1[MAXN / 2], s2[MAXN / 2];
    38 int sum[MAXN];
    39 
    40 int main() {
    41     Complex* e = 0;
    42     fft_prepare(MAXN, e);
    43     while(scanf("%s%s",s1,s2) != EOF) {
    44         int n1 = strlen(s1);
    45         int n2 = strlen(s2);
    46         int n = 1;
    47         while(n < n1 * 2 || n < n2 * 2) n <<= 1;
    48         for(int i = 0; i < n; ++i) {
    49             x1[i] = i < n1 ? s1[n1 - 1 - i] - '0' : 0;
    50             x2[i] = i < n2 ? s2[n2 - 1 - i] - '0' : 0;
    51         }
    52 
    53         dft(x1, n, 1, e, MAXN);
    54         dft(x2, n, 1, e, MAXN);
    55         for(int i = 0; i < n; ++i) x1[i] = x1[i] * x2[i];
    56         dft(x1, n, -1, e, MAXN);
    57         for(int i = 0; i < n; ++i) x1[i] /= n;
    58 
    59         for(int i = 0; i < n; ++i) sum[i] = round(x1[i].real());
    60         for(int i = 0; i < n; ++i) {
    61             sum[i + 1] += sum[i] / 10;
    62             sum[i] %= 10;
    63         }
    64 
    65         n = n1 + n2 - 1;
    66         while(sum[n] <= 0 && n > 0) --n;
    67         for(int i = n; i >= 0;i--) printf("%d", sum[i]);
    68         puts("");
    69     }
    70 }
    View Code

    11、求解线性同余方程组(POJ 2891 exgcd)

     1 void exgcd(LL a, LL b, LL &d, LL &x, LL &y) {
     2     if(!b) d = a, x = 1, y = 0;
     3     else {
     4         exgcd(b, a % b, d, y, x);
     5         y -= x * (a / b);
     6     }
     7 }
     8 
     9 int main() {
    10     LL k, a1, a2, r1, r2;
    11     while(scanf("%I64d", &k) != EOF) {
    12         bool flag = true;
    13         scanf("%I64d%I64d", &a1, &r1);
    14         for(int i = 1; i < k; ++i) {
    15             scanf("%I64d%I64d", &a2, &r2);
    16             if(!flag) continue;
    17             LL r = r2 - r1, d, k1, k2;
    18             exgcd(a1, a2, d, k1, k2);
    19             if(r % d) flag = false;
    20             LL t = a2 / d;
    21             k1 = (r / d * k1 % t + t) % t;
    22             r1 = r1 + a1 * k1;
    23             a1 = a1 / d * a2;
    24         }
    25         printf("%I64d
    ", flag ? r1 : -1);
    26     }
    27 }
    View Code
  • 相关阅读:
    This counter can increment, decrement or skip ahead by an arbitrary amount
    LUT4/MUXF5/MUXF6 logic : Multiplexer 8:1
    synthesisable VHDL for a fixed ratio frequency divider
    Bucket Brigade FIFO SRL16E ( VHDL )
    srl16e fifo verilog
    DualPort Block RAM with Two Write Ports and Bytewide Write Enable in ReadFirst Mode
    Parametrilayze based on SRL16 shift register FIFO
    stm32 spi sdcard fatfs
    SPI bus master for System09 (2)
    SQLSERVER中的自旋锁
  • 原文地址:https://www.cnblogs.com/oyking/p/3269151.html
Copyright © 2011-2022 走看看