社区讨论

相同代码多次提交,一会 AC 一会 TLE

P3803【模板】多项式乘法(FFT)参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lvw0kmhm
此快照首次捕获于
2024/05/07 14:32
2 年前
此快照最后确认于
2024/05/07 18:48
2 年前
查看原帖
相同代码多次提交,一会 AC,一会 TLE。怀疑评测系统执行程序的速度存在抖动。

C++ 代码:
CPP
#include <cmath>
#include <complex>
#include <iostream>
#include <vector>

using namespace std;

const int N = 2'097'152;
const double PI = acos(-1);

complex<double> unit_roots[N];

complex<double> get_unit_root(int n, int m)
{
    return { cos(m * 2 * PI / n), sin(m * 2 * PI / n) };
}

vector<complex<double>> fft(const vector<double>& coeffs, int start, int interval, int count)
{
    if (count == 1)
        return { coeffs[start] };
    vector<complex<double>> subresults[2]{ fft(coeffs, start, interval * 2, count / 2), fft(coeffs, start + interval, interval * 2, count / 2) };
    vector<complex<double>> results(count);
    for (int i = 0; i < count / 2; ++i)
    {
        results[i] = subresults[0][i] + unit_roots[N / count * i] * subresults[1][i];
        results[i + count / 2] = subresults[0][i] - unit_roots[N / count * i] * subresults[1][i];
    }
    return results;
}

vector<complex<double>> ifft(const vector<complex<double>>& values, int start, int interval, int count)
{
    if (count == 1)
        return { values[start] };
    vector<complex<double>> subresults[2]{ ifft(values, start, interval * 2, count / 2), ifft(values, start + interval, interval * 2, count / 2) };
    vector<complex<double>> results(count);
    for (int i = 0; i < count / 2; ++i)
    {
        results[i] = (subresults[0][i] + 1.0 / unit_roots[N / count * i] * subresults[1][i]) / 2.0;
        results[i + count / 2] = (subresults[0][i] - 1.0 / unit_roots[N / count * i] * subresults[1][i]) / 2.0;
    }
    return results;
}

int main()
{
    int n1 = 0, n2 = 0, first_nonzero_pos = 0;
    for (int i = 0; i < N; ++i)
        unit_roots[i] = get_unit_root(N, i);
    cin >> n1 >> n2;
    vector<double> a_digits(N), b_digits(N);
    for (int i = 0; i < n1 + 1; ++i)
        cin >> a_digits[i];
    for (int i = 0; i < n2 + 1; ++i)
        cin >> b_digits[i];
    vector<complex<double>> a_points = fft(a_digits, 0, 1, N);
    vector<complex<double>> b_points = fft(b_digits, 0, 1, N);
    vector<complex<double>> c_points(N);
    for (int i = 0; i < N; ++i)
        c_points[i] = a_points[i] * b_points[i];
    vector<complex<double>> c_digits_complex = ifft(c_points, 0, 1, N);
    vector<int> c_digits(N);
    for (int i = 0; i < n1 + n2 + 1; ++i)
        c_digits[i] = lround(c_digits_complex[i].real());
    for (int i = 0; i < n1 + n2 + 1; ++i)
        cout << c_digits[i] << ' ';
    cout << '\n';
    return 0;
}

提交记录:
这些 TLE 的测试点,时间都只是略微超出了 22 秒。
(经过我坚持不懈、持之以恒的反复提交,我终于 AC 了这道题!)

回复

2 条回复,欢迎继续交流。

正在加载回复...