洛谷P3338 力

題意:ide

解:函數

介紹兩種方法。spa

首先能夠把那個最後除的qi拆掉。code

①分先後兩部分處理。blog

前一部分能夠看作是個卷積。下面的平方不拆開,直接當作gi-j便可。get

後一部分按照套路,把循環變量改爲從0開始,反轉q,以後也是卷積。it

②直接構造函數卷積。io

題解event

我寫的第一種。class

 

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 
 5 const int N = 100010;
 6 const double pi = 3.1415926535897932384626;
 7 
 8 struct cp {
 9     double x, y;
10     cp(double X = 0, double Y = 0) {
11         x = X;
12         y = Y;
13     }
14     inline cp operator +(const cp &w) const {
15         return cp(x + w.x, y + w.y);
16     }
17     inline cp operator -(const cp &w) const {
18         return cp(x - w.x, y - w.y);
19     }
20     inline cp operator *(const cp &w) const {
21         return cp(x * w.x - y * w.y, x * w.y + y * w.x);
22     }
23 }f[N << 2], g[N << 2], h[N << 2];
24 
25 int r[N << 2];
26 
27 inline void FFT(int n, cp *a, int f) {
28     for(int i = 0; i < n; i++) {
29         if(i < r[i]) {
30             std::swap(a[i], a[r[i]]);
31         }
32     }
33 
34     for(int len = 1; len < n; len <<= 1) {
35         cp Wn(cos(pi / len), f * sin(pi / len));
36         for(int i = 0; i < n; i += (len << 1)) {
37             cp w(1, 0);
38             for(int j = 0; j < len; j++) {
39                 cp t = a[i + len + j] * w;
40                 a[i + len + j] = a[i + j] - t;
41                 a[i + j] = a[i + j] + t;
42                 w = w * Wn;
43             }
44         }
45     }
46 
47     if(f == -1) {
48         for(int i = 0; i <= n; i++) {
49             a[i].x /= n;
50         }
51     }
52     return;
53 }
54 
55 int main() {
56     int n;
57     scanf("%d", &n);
58     n--;
59     for(int i = 0; i <= n; i++) {
60         scanf("%lf", &f[i].x);
61         h[n - i].x = f[i].x;
62     }
63     g[0].x = 1;
64     for(int i = 1; i <= n; i++) {
65         g[i].x = ((double)(1)) / i / i;
66     }
67 
68     int len = 2, lm = 1;
69     while(len <= n + n) {
70         len <<= 1;
71         lm++;
72     }
73     for(int i = 1; i <= len; i++) {
74         r[i] = (r[i >> 1] >> 1) | ((i & 1) << (lm - 1));
75     }
76 
77     FFT(len, f, 1);
78     FFT(len, g, 1);
79     FFT(len, h, 1);
80     for(int i = 0; i <= len; i++) {
81         f[i] = f[i] * g[i];
82         g[i] = g[i] * h[i];
83     }
84     FFT(len, f, -1);
85     FFT(len, g, -1);
86 
87     for(int i = 0; i <= n; i++) {
88         printf("%lf\n", f[i].x - g[n - i].x);
89     }
90 
91     return 0;
92 }
AC代碼
相關文章
相關標籤/搜索