[Luo Gu P3338] ZJOI2014 force

Problem Description

Gives the n number qi, given Fj is defined as follows:
\ [F_j = \ sum_ {I <J} \ {FRAC Q_I Q_j} {(ij of) ^ 2} - \ sum_ {I> J} \ {Q_I FRAC q_j} {(ij) ^ 2
} \] order Ei = Fi / qi, seeking Ei.

Input Format

A first line integer n.

The next n lines each enter a number, represented by the i-th row qi.

Output Format

n row, the i-th output line Ei.

The answer is not more than the standard error of 1e-2 can be.

Sample input

5
4006373.885184
15375036.435759
1717456.469144
8514941.004912
1410681.345880

Sample Output

-16838672.693
3439.793
7509018.566
4595686.886
10903040.872

Resolve

First, we look first to simplify the equation:
\ [\} the begin align = left {E [I] = & \ {F. FRAC [I] {P} [I]} & \\ = \ sum_ {J <{I} \ frac {p [j]}
{(ij) ^ 2}} - \ sum_ {j> i} {\ frac {p [j]} {(ij) ^ 2}} \ end {align} \] then, set \ (F1 [I] = P [I], G [I] = \ FRAC {. 1} {I ^ 2} \) , then the original equation can be simplified to give:
\ [E [I] = \ sum_ {J = 1} ^ {i-1
} f1 [j] * g [ij] - \ sum_ {j = i + 1} ^ {n} f1 [j] * g [ji] \] to the right of the two equations becomes part of the same form, we may assume \ (F2 [I] = F1 [I-n-+. 1] \) , is about \ (F1 \) inverted to give \ (F2 \) , we can achieve our aim:
\ [E [i] = \ sum_ {j = 1} ^ {i-1} f1 [j] * g [ij] - \ sum_ {j = 1} ^ {i-1} f2 [j] * g [ij] \ ]
was observed in the form of polynomial equations form very similar to the convolution, the convolution is first \ (i-1 \) coefficients power terms. Therefore, we can use the FFT are determined \ (f1 \) and \ (g \) , \ (F2 \) and \ (g \) convolution, then the answer is the difference between the number of items of correspondence.

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#define N 400002
using namespace std;
const double PI=acos(-1);
struct Complex{
    double r,i;
}a[N],b[N];
Complex operator + (Complex a,Complex b) {return (Complex){a.r+b.r,a.i+b.i};}
Complex operator - (Complex a,Complex b) {return (Complex){a.r-b.r,a.i-b.i};}
Complex operator * (Complex a,Complex b) {return (Complex){a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r};}
int n=1,m,i,lim=1,r[N];
double f1[N],f2[N],g[N],ansa[N],ansb[N];
void trans()
{
    double tmp[N];
    for(int i=m;i>=1;i--) tmp[m-i+1]=f2[i];
    for(int i=1;i<=m;i++) f2[i]=tmp[i];
}
void FFT(Complex *a,int inv)
{
    for(int i=0;i<n;i++){
        if(i<r[i]) swap(a[i],a[r[i]]);
    }
    for(int l=2;l<=n;l*=2){
        int mid=l/2;
        Complex omg=(Complex){cos(2*PI/l),inv*sin(2*PI/l)};
        for(int i=0;i<n;i+=l){
            Complex w=(Complex){1,0};
            for(int j=0;j<mid;j++,w=w*omg){
                Complex tmp=a[i+j+mid]*w;
                a[i+j+mid]=a[i+j]-tmp;
                a[i+j]=a[i+j]+tmp;
            }
        }
    }
}
void solve(double *f,double *g,double *ans)
{
    for(int i=0;i<n;i++) a[i].r=f[i],a[i].i=0;
    for(int i=0;i<n;i++) b[i].r=g[i],b[i].i=0;
    FFT(a,1);FFT(b,1);
    for(int i=0;i<n;i++) a[i]=a[i]*b[i];
    FFT(a,-1);
    for(int i=1;i<=m;i++) ans[i]=a[i].r/n;
}
int main()
{
    cin>>m;
    while(n<2*m) n*=2;
    while((1<<lim)<n) lim++;
    for(i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(lim-1));
    for(i=1;i<=m;i++){
        cin>>f1[i];
        g[i]=1.0/i/i;
        f2[i]=f1[i];
    }
    trans();
    solve(f1,g,ansa);
    solve(f2,g,ansb);
    for(i=1;i<=m;i++) printf("%.3lf\n",ansa[i]-ansb[m-i+1]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/11105283.html