洛谷P3338 力

题意:

解:

介绍两种方法。

首先可以把那个最后除的qi拆掉。

①分前后两部分处理。

前一部分可以看做是个卷积。下面的平方不拆开,直接看成gi-j即可。

后一部分按照套路,把循环变量改成从0开始,反转q,之后也是卷积。

②直接构造函数卷积。

题解

我写的第一种。

 

 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代码

 

posted @ 2019-01-09 22:02  huyufeifei  阅读(159)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜