Advertisement
Guest User

Problem E

a guest
Oct 1st, 2012
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.24 KB | None | 0 0
  1. #define _CRT_SECURE_NO_DEPRECATE
  2. #include <algorithm>
  3. #include <string>
  4. #include <set>
  5. #include <map>
  6. #include <vector>
  7. #include <queue>
  8. #include <iostream>
  9. #include <iterator>
  10. #include <cmath>
  11. #include <cstdio>
  12. #include <cstdlib>
  13. #include <sstream>
  14. #include <fstream>
  15. #include <ctime>
  16. #include <cstring>
  17. #pragma comment(linker, "/STACK:66777216")
  18. using namespace std;
  19. #define pb push_back
  20. #define ppb pop_back
  21. #define pi 3.1415926535897932384626433832795028841971
  22. #define mp make_pair
  23. #define x first
  24. #define y second
  25. #define pii pair<int,int>
  26. //#define pdd pair<double,double>
  27. #define INF 1000000000
  28. #define FOR(i,a,b) for (int _n(b), i(a); i <= _n; i++)
  29. #define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;i--)
  30. #define all(c) (c).begin(), (c).end()
  31. #define SORT(c) sort(all(c))
  32. #define rep(i,n) FOR(i,1,(n))
  33. #define rept(i,n) FOR(i,0,(n)-1)
  34. #define L(s) (int)((s).size())
  35. #define C(a) memset((a),0,sizeof(a))
  36. #define VI vector <int>
  37. #define ll long long
  38. #define problem "factorial"
  39.  
  40. struct pdd {
  41.     double x, y;
  42.     pdd() : x(0), y(0) {}
  43.     pdd(double _x, double _y) : x(_x), y(_y) {}
  44. };
  45. inline pdd operator -(const pdd &a, const pdd &b) {
  46.     return pdd(a.x - b.x, a.y - b.y);
  47. }
  48. inline pdd operator +(const pdd &a, const pdd &b) {
  49.     return pdd(a.x + b.x, a.y + b.y);
  50. }
  51. inline pdd operator *(const pdd &a, const pdd &b) {
  52.     return pdd(a.x * b.x - a.y * b.y, a.x * b.y + b.x * a.y);
  53. }
  54. const int N = 1 << 17;
  55. int a,b,c,d,i,j,n,m,k;
  56. int rv[20][N + 1];
  57.  
  58. pdd root1[N + 1], root2[N + 1];
  59. pdd ta[N + 1], tb[N + 1];
  60.  
  61. const int MOD = 1000;
  62. void fft(pdd *a, int n, pdd * root) {
  63.     int l = 0;
  64.     while ((1 << l) < n) ++l;
  65.     rept(i, n) {
  66.         if (rv[l][i] < i) swap(a[i], a[rv[l][i]]);
  67.     }
  68.  
  69.     int mul = N / n;
  70.     for (int cur = 2; cur <= n; cur *= 2) {
  71.         int d = (n / cur) * mul;
  72.         int half = cur / 2;
  73.         for (int pos = 0; pos < n; pos += cur) {
  74.             rept(i, half) {
  75.                 pdd v1 = a[pos + i], v2 = root[i * d] * a[pos + i + half];
  76.                 a[pos + i] = v1 + v2;
  77.                 a[pos + i + half] = v1 - v2;
  78.             }
  79.         }
  80.     }
  81.  
  82.     if (root == root2) {
  83.         rept(i, n) {
  84.             a[i].x /= n;
  85.             a[i].y /= n;
  86.         }
  87.     }
  88. }
  89.  
  90. inline void normalize(VI &res) {
  91.     rept(i, L(res)) {
  92.         if (res[i] >= MOD && i + 1 >= L(res)) res.pb(0);
  93.         if (res[i] >= MOD) {
  94.             res[i + 1] += res[i] / MOD;
  95.             res[i] %= MOD;
  96.         }
  97.     }
  98.     while (L(res) > 1 && res.back() == 0) res.ppb();
  99. }
  100.  
  101. inline void normalize(vector<ll> &res) {
  102.     rept(i, L(res)) {
  103.         if (res[i] >= MOD && i + 1 >= L(res)) res.pb(0);
  104.         if (res[i] >= MOD) {
  105.             res[i + 1] += res[i] / MOD;
  106.             res[i] %= MOD;
  107.         }
  108.     }
  109.     while (L(res) > 1 && res.back() == 0) res.ppb();
  110. }
  111.  
  112. vector<ll> tmp;
  113. inline void mul(const VI &a, const VI &b, VI &res) {
  114.     if (L(a) <= 8 && L(b) <= 8) {
  115.         res.resize(L(a) + L(b));
  116.         rept(i, L(a)) {
  117.             rept(j, L(b)) {
  118.                 res[i + j] += a[i] * b[j];
  119.             }
  120.         }
  121.  
  122.         normalize(res);
  123.         return;
  124.     }
  125.  
  126.     int t = 1;
  127.     while (t < L(a) || t < L(b)) t *= 2;
  128.     t *= 2;
  129.     rept(i, t) {
  130.         if (i >= L(a)) ta[i] = pdd(0, 0); else
  131.         ta[i] = pdd(a[i], 0);
  132.         if (i >= L(b)) tb[i] = pdd(0, 0); else
  133.         tb[i] = pdd(b[i], 0);
  134.     }
  135.  
  136.     fft(ta, t, root1);
  137.     fft(tb, t, root1);
  138.  
  139.     rept(i, t) ta[i] = ta[i] * tb[i];
  140.  
  141.     fft(ta, t, root2);
  142.     tmp.resize(t);
  143.     rept(i, t) {
  144.         tmp[i] = (ll)(ta[i].x + 0.5);
  145.     }
  146.     normalize(tmp);
  147.     res.resize(L(tmp));
  148.     rept(i, L(tmp)) res[i] = tmp[i];
  149. }
  150. void calc(VI coef, VI &ans) {
  151.     if (coef.empty()) {
  152.         ans.resize(1);
  153.         ans[0] = 1;
  154.         return;
  155.     }
  156.     if (L(coef) == 1) {
  157.         ans.resize(1);
  158.         ans[0] = coef[0];
  159.         return;
  160.     }
  161.  
  162.     VI c1, c2;
  163.     c1.resize((L(coef) + 1) / 2);
  164.     c2.resize(L(coef) / 2);
  165.     rept(i, L(coef)) {
  166.         if (i % 2) c2[i / 2] = coef[i]; else
  167.         c1[i / 2] = coef[i];
  168.     }
  169.  
  170.     VI a1, a2;
  171.     calc(c1, a1);
  172.     calc(c2, a2);
  173.  
  174.     mul(a1, a2, ans);
  175. }
  176. int main() {
  177.     rv[0][0] = 0;
  178.     rept(i, 17) {
  179.         rept(j, 1 << i) {
  180.             rv[i + 1][j | 1 << i] = rv[i][j] * 2 + 1;
  181.             rv[i + 1][j] = rv[i][j] * 2;
  182.         }
  183.     }
  184.     rept(i, N) {
  185.         root1[i] = pdd(cos(2.0 * pi * i / N), sin(2.0 * pi * i / N));
  186.         root2[i] = pdd(cos(2.0 * pi * i / N), -sin(2.0 * pi * i / N));
  187.     }
  188.     freopen(problem ".in","r",stdin);
  189.     freopen(problem ".out","w",stdout);
  190.     VI ans, coef;
  191.     scanf("%d", &n);
  192.     rep(i, n) coef.pb(i);
  193.  
  194.     calc(coef, ans);
  195.     FORD(i, L(ans) - 1, 0) {
  196.         if (i == L(ans) - 1) printf("%d", ans[i]); else
  197.         printf("%03d", ans[i]);
  198.     }
  199.     printf("\n");
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement