• LG P3338 [ZJOI2014]力


    Description

    给出 $n$ 个数 $q_1,q_2, dots q_n$,定义

    $$F_j~=~sum_{i = 1}^{j - 1} frac{q_i imes q_j}{(i - j)^2}~-~sum_{i = j + 1}^{n} frac{q_i imes q_j}{(i - j)^2}$$

    $$E_i~=~frac{F_i}{q_i}$$

    对 $1 leq i leq n$,求 $E_i$ 的值。

    Solution

    原式可化为$$sum_{i=1}^{j-1} frac{q_i}{(i-j)^2} - sum_{i=j+1}^n frac{q_i}{(i-j)^2}$$

    设$f_i=q_i,g_i=frac 1{i^2}$

    令$f_0=g_0=0$

    则原式化为$$sum_{i=1}^j f_i imes g_{j-i} - sum_j^n f_i imes g_{i-j}$$

    设$f'_i = f_{n-i}$,则原式化为

    $$sum_{i=0}^j f_i imes g_{j-i} - sum_{i=0}^{n-j} f'_{n-j-i} imes g_i$$

    两次FFT求解

    #include<iostream>
    #include<complex>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,s=2,tot=1,rev[400005];
    const double pi=acos(-1);
    complex<double> f[400005],g[400005],ff[400005];
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    void fft(complex<double>*a,int n,int inv)
    {
        for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
        for(int i=1;i<n;i*=2)
        {
            complex<double>wn=exp(complex<double>(0,inv*pi/i));
            for(int j=0;j<n;j+=i*2)
            {
                complex<double>w(1,0);
                for(int k=j;k<i+j;k++)
                {
                    complex<double>x=a[k],y=w*a[k+i];
                    a[k]=x+y,a[k+i]=x-y,w*=wn;
                }
            }
        }
        if(inv==-1) for(int i=0;i<n;i++) a[i]/=n;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) scanf("%lf",&f[i]),ff[n-i]=f[i];
        for(int i=1;i<=n;i++) g[i]=1.0/i/i;
        while(s<n*2) s<<=1,tot++;
        for(int i=0;i<s;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(tot-1));
        fft(f,s,1),fft(g,s,1),fft(ff,s,1);
        for(int i=0;i<s;i++) f[i]*=g[i];
        for(int i=0;i<s;i++) ff[i]*=g[i];
        fft(f,s,-1),fft(ff,s,-1);
        for(int i=1;i<=n;i++) printf("%.3lf
    ",f[i].real()-ff[n-i].real());
        return 0;
    }
  • 相关阅读:
    ListBoxAddItems() 不重复添加Edit1
    Get_HD_Serial() 获得磁盘驱动器序列号
    JavaScript是否可实现多线程 — 深入理解JavaScript定时机制
    测测你是否近视!
    [趣闻]Google 员工架飞索去总部蹭饭
    datagridview回车事件
    抄过来的eGroupWare的一些资源
    DataGridView 添加ComboBox
    Chapter 1: Introducing the Project: TheBeerHouse
    Linux操作系统学习线路图
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14021557.html
Copyright © 2020-2023  润新知