zoukankan      html  css  js  c++  java
  • [BZOJ2194] 快速傅立叶之二

    2194: 快速傅立叶之二

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 1993  Solved: 1201
    [Submit][Status][Discuss]

    Description

    请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。

    Input

    第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i < N)。

    Output

    输出N行,每行一个整数,第i行输出C[i-1]。

    Sample Input

    5
    3 1
    2 4
    1 1
    2 4
    1 4

    Sample Output

    24
    12
    10
    6
    1
     
    先把f逆序,卷积之后再逆序输出
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 262144;
    struct comp{
        double x, y;
        comp(double _x = 0, double _y = 0){
            x = _x;
            y = _y;
        }
        friend comp operator * (const comp &a, const comp &b){
            return comp(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
        }
        friend comp operator + (const comp &a, const comp &b){
            return comp(a.x + b.x, a.y + b.y);
        }
        friend comp operator - (const comp &a, const comp &b){
            return comp(a.x - b.x, a.y - b.y);
        }
    }f[maxn], g[maxn];
    int rev[maxn];
    void dft(comp A[], int len, int kind){
        for(int i = 0; i < len; i++){
            if(i < rev[i]){
                swap(A[i], A[rev[i]]);
            }
        }
        for(int i = 1; i < len; i <<= 1){
            comp wn(cos(acos(-1.0) / i), kind * sin(acos(-1.0) / i));
            for(int j = 0; j < len; j += (i << 1)){
                comp tmp(1, 0);
                for(int k = 0; k < i; k++){
                    comp s = A[j + k], t = tmp * A[i + j + k];
                    A[j + k] = s + t;
                    A[i + j + k] = s - t;
                    tmp = tmp * wn;
                }
            }
        }
        if(kind == -1) for(int i = 0; i < len; i++) A[i].x /= len;
    }
    int main(){
        int n, len, L = 0;
        scanf("%d", &n); 
        for(len = 1; len < n + n - 1; len <<= 1, L++);
        for(int i = 0; i < len; i++){
            rev[i] = rev[i >> 1] >> 1 | (i & 1) << L - 1;
        }
        for(int i = 0; i < n; i++)
            scanf("%lf%lf", &f[n - i - 1].x, &g[i].x);
        dft(f, len, 1); dft(g, len, 1);
        for(int i = 0; i < len; i++) f[i] = f[i] * g[i];
        dft(f, len, -1);
        for(int i = n - 1; ~i; i--) printf("%d
    ", (int)(f[i].x + 0.5));
        return 0; 
    }
  • 相关阅读:
    二叉树的节点删除
    PHP开启错误日志详细说明
    jsonpath模块
    Gunicorn-配置详解
    Vmware创建虚拟机步骤说明,详细配置解释
    Python multiprocessing使用详解
    Python定时任务框架apscheduler
    Access-Control-Allow-Origin跨域解决及详细介绍
    web安全:x-content-type-options头设置
    sqlalchemy的基本操作大全
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/11759862.html
Copyright © 2011-2022 走看看