DOJ 1003

已知:

\[f(1)=1\]

\[f(n)=(n-1)f(1)+(n-2)f(2)+\cdots +f(n-1)\]

求第n项的数

 

题解:

推一推,可以推出

于是

然而。。蒟蒻不会写资辞负数的高精度

所以乱搞搞

高精度搞搞就好了

 

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<vector>
  7 using namespace std;
  8 typedef unsigned long long ull;
  9 typedef vector < ull > vull;
 10 vull :: iterator it;
 11 const double PI = acos(-1.0);
 12 const int N = 1000005;
 13 struct cp {
 14     double r, i;
 15     cp (double a = 0.0, double b = 0.0) :
 16         r(a), i(b) {}
 17     inline void operator= (const int &p) {r = p, i = 0.0;}
 18     inline cp operator+ (const cp &o) {return cp(r + o.r, i + o.i);}
 19     inline cp operator- (const cp &o) {return cp(r - o.r, i - o.i);}
 20     inline cp operator* (const cp &o) {
 21         return cp(r * o.r - i * o.i, r * o.i + i * o.r);
 22     }
 23 } pa[N], pb[N];
 24 
 25 inline void rader(cp *a, int n) {
 26     int j = n >> 1;
 27     for (int i = 1; i < n - 1; ++i) {
 28         if (i < j) swap(a[i], a[j]);
 29         int k = n >> 1;
 30         while (j >= k) {
 31             j -= k; k >>= 1;
 32         } if (j < k) j += k;
 33     }
 34 }
 35 
 36 inline void fft(cp *a, int n, bool idft = false) {
 37     rader(a, n);
 38     double pi = idft ? -PI : PI;
 39     for (int h = 2; h <= n; h <<= 1) {
 40         cp omgn(cos(2 * pi / h), sin(2 * pi / h));
 41         for (int j = 0; j < n; j += h) {
 42             cp omg(1, 0);
 43             for (int k = j; k < j + h / 2; ++k) {
 44                 cp u = a[k], v = omg * a[k + h / 2];
 45                 a[k] = u + v, a[k + h / 2] = u - v;
 46                 omg = omg * omgn;
 47             }
 48         }
 49     }
 50     if (idft) for (int i = 0; i < n; ++i) a[i].r /= n;
 51 }
 52 
 53 inline vull mul(vull &a, vull &b) {
 54     int la = 0, lb = 0, s = 0;
 55     vull res;
 56     for (it = a.begin(); it != a.end(); ++it)
 57         pa[la++] = *it;
 58     for (it = b.begin(); it != b.end(); ++it)
 59         pb[lb++] = *it;
 60     while ((1 << s) < la + lb) ++s; s = 1 << s;
 61     for (int i = la; i < s; ++i) pa[i] = 0;
 62     for (int i = lb; i < s; ++i) pb[i] = 0;
 63     fft(pa, s); fft(pb, s);
 64     for (int i = 0; i < s; ++i) pa[i] = pa[i] * pb[i];
 65     fft(pa, s, true);
 66     res.resize(la + lb - 1);
 67     for (int i = 0; i <= la + lb - 2; ++i)
 68         res[i] = (ull) (pa[i].r + 0.5);
 69     return res;
 70 }
 71 
 72 const int BASE = 1000, WIDTH = 3;
 73 struct Bignum {
 74     vull s;
 75     inline Bignum operator= (ull num) {
 76         s.clear();
 77         do {
 78             s.push_back(num % BASE);
 79             num /= BASE;
 80         } while (num > 0);
 81         return *this;
 82     }
 83 
 84     inline void operator= (const string &str) {
 85         s.clear();
 86         ull x;
 87         int len = (str.size() - 1) / WIDTH + 1, size = str.size();
 88         for (int i = 0; i < len; ++i) {
 89             int end = size - i * WIDTH;
 90             int start = max(0, end - WIDTH);
 91             sscanf(str.substr(start, end - start).c_str(), "%llu", &x);
 92             s.push_back(x);
 93         }
 94         clean();
 95     }
 96 
 97     inline Bignum clean() {
 98         while (!s.back() and !s.empty()) {
 99             s.pop_back();
100         }
101         if (s.empty()) s.push_back(0);
102         return *this;
103     }
104 
105     inline void cc() {
106         int size = s.size();
107         for (int i = 0; i < size; ++i) {
108             if (s[i] >= BASE) {
109                 if (i + 1 == size)
110                     s.push_back(s[i] / BASE);
111                 else
112                     s[i + 1] += s[i] / BASE;
113                 s[i] %= BASE;
114             }
115         }
116     }
117 
118     inline void print() {
119         printf("%llu", s.back());
120         for (int i = s.size() - 2; i >= 0; --i) {
121             char buf[20];
122             sprintf(buf, "%03llu", s[i]);
123             int len = strlen(buf);
124             for (int j = 0; j < len; ++j)
125                 putchar(buf[j]);
126         }
127     }
128 
129     inline Bignum operator+ (const Bignum& o) {
130         Bignum res; res.s.clear();
131         int sza = s.size(), szb = o.s.size();
132         ull g = 0;
133         for (int i = 0;; ++i) {
134             if (!g and i >= sza and i >= szb) break;
135             ull x = g;
136             if (i < sza) x += s[i];
137             if (i < szb) x += o.s[i];
138             res.s.push_back(x % BASE);
139             g = x / BASE;
140         }
141         res.cc();
142         return res;
143     }
144 
145     inline Bignum& operator += (const Bignum &o) {
146         *this = *this + o;
147         return *this;
148     }
149 
150 
151     inline friend Bignum operator* (Bignum &a, Bignum &b) {
152         Bignum res;
153         res.s = mul(a.s, b.s);
154         res.cc();
155         return res;
156     }
157 
158 };
159 
160 struct Mat {
161     Bignum d[2][2];
162     Mat(int u = 0, int i = 0, int o = 0, int p = 0) {
163         d[0][0] = u; d[0][1] = i;
164         d[1][0] = o; d[1][1] = p;
165     }
166     inline Mat operator* (Mat &o) {
167         Mat res;
168         for (int i = 0; i < 2; ++i)
169             for (int j = 0; j < 2; ++j)
170                 for (int k = 0; k < 2; ++k)
171                     res.d[i][j] += d[i][k] * o.d[k][j];
172         return res;
173     }
174 } A(2, 1, 1, 1), ans(1, 0, 0, 1);
175 
176 
177 int main() {
178     int n; scanf("%d", &n);
179     if (n < 3) {
180         puts("1"); return 0;
181     }
182     if (n == 3) {
183         puts("3"); return 0;
184     }
185     --n;
186     while (n) {
187         if (n & 1) ans = A * ans;
188         A = A * A; n >>= 1;
189     }
190     ans.d[0][1].print();
191     return 0;
192 }
View Code

 

posted @ 2017-05-13 22:48  p0ny  阅读(149)  评论(0编辑  收藏  举报