BZOJ 3527: [ZJOI2014]力(FFT)

题意

给出n个数qi,给出Fj的定义如下:

Fj=i<jqiqj(ij)2i>jqiqj(ij)2.

Ei=Fi/qi,求Ei.

题解

一开始没发现求Ei... 其实题目还更容易想了...

Ei=j<iqj(ij)2j>iqj(ij)2

这个东西就是转换成求两个一样的东西就行了。

就是求sumi=j<iqj(ij)2.

这个就是可以转换成求一个卷积形式就行了。

注意多项式乘法格式是这样的:

A0+A1x+...+Anxn

B0+B1x+...+Bnxn

AB的卷积为C,则$$C_i=\sum \limits {j \le i}A_j*B$$.

发现ij那个形式似乎就可以满足本题的形式。

所以令Bi=1i2就行了,然后Ai=qi.

对于这个求两边卷积就行了23333

注意有的细节要处理一下,就是要清空一些数组,

注意一下下标(思维要清楚),而且也要令A0=B0=0

而且之前求Bi的时候,i2会爆long long

代码

/************************************************************** Problem: 3527 User: zjp_shadow Language: C++ Result: Accepted Time:3688 ms Memory:32012 kb ****************************************************************/ #include <bits/stdc++.h> #define For(i, l, r) for(register int i = (l), _end_ = (int)(r); i <= _end_; ++i) #define Fordown(i, r, l) for(register int i = (r), _end_ = (int)(l); i >= _end_; --i) #define Set(a, v) memset(a, v, sizeof(a)) using namespace std; bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;} bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;} inline int read() { int x = 0, fh = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar() ) if (ch == '-') fh = -1; for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ '0'); return x * fh; } void File() { #ifdef zjp_shadow freopen ("P3527.in", "r", stdin); freopen ("P3527.out", "w", stdout); #endif } struct Complex { double re, im; }; inline Complex operator + (const Complex &lhs, const Complex &rhs) { return (Complex) {lhs.re + rhs.re, lhs.im + rhs.im}; } inline Complex operator - (const Complex &lhs, const Complex &rhs) { return (Complex) {lhs.re - rhs.re, lhs.im - rhs.im}; } inline Complex operator * (const Complex &lhs, const Complex &rhs) { return (Complex) {lhs.re * rhs.re - lhs.im * rhs.im, lhs.re * rhs.im + rhs.re * lhs.im}; } const int N = 1 << 19; int n_, n; double f[N], g[N]; const double Pi = acos(-1.0); int r[N]; void FFT(Complex P[], int opt) { For (i, 0, n - 1) if (i < r[i]) swap(P[i], P[r[i]]); for (int i = 2; i <= n; i <<= 1) { Complex Wi = (Complex) {cos(2 * Pi / i), opt * sin(2 * Pi / i)}; int p = i / 2; for (int j = 0; j < n; j += i) { Complex x = (Complex) {1.0, 0.0}; For (k, 0, p - 1) { Complex u = P[j + k], v = x * P[j + k + p]; P[j + k] = u + v; P[j + k + p] = u - v; x = x * Wi; } } } } int m; void Mult(Complex a[], Complex b[]) { int cnt = 0; for (n = 1; n <= m; n <<= 1) ++ cnt; For (i, 1, n - 1) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (cnt - 1) ); FFT(a, 1); FFT(b, 1); For (i, 0, n - 1) a[i] = a[i] * b[i]; FFT(a, -1); For (i, 0, n - 1) a[i].re = a[i].re / n; } double ans[N]; Complex a[N], b[N]; int main () { //int n1 = read(), n2 = read(), File(); n_ = read(); m = n_ + n_; For (i, 1, n_) { scanf("%lf", &f[i]); g[i] = (double)1.0 / ((long long)i * (long long)i); } For (i, 0, n_) a[i].re = f[i], a[i].im = 0; For (i, 0, n_) b[i].re = g[i], b[i].im = 0; Mult(a, b); For (i, 1, n_) ans[i] += a[i].re; reverse(f + 1, f + 1 + n_); For (i, 0, n - 1) a[i].re = f[i], a[i].im = 0; For (i, 0, n - 1) b[i].re = g[i], b[i].im = 0; Mult(a, b); For (i, 1, n_) ans[n_ - i + 1] -= a[i].re; For (i, 1, n_) printf ("%.4lf\n", ans[i]); return 0; }

__EOF__

本文作者zjp_shadow
本文链接https://www.cnblogs.com/zjp-shadow/p/8435930.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zjp_shadow  阅读(173)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示