zoukankan      html  css  js  c++  java
  • ZJOI2014 力

    传送门

    一道FFT的标准练习题。

    (q_i)除进去,就可以得到(E(j) = sum_{i<j}frac{q_j}{(i-j)^2} - sum_{i > j}frac{q_j}{(i-j)^2}).

    把这个式子前后两部分分别拆开,设(f(i) = q_i),(g(i) = frac{1}{i^2}),那么前一部分就是(sum_{i=0}^j f(j) * g(i-j)),而后一部分就是(sum_{i = 0}^{n - j - 1}f(i+j) * g(j))

    后半部分好像不大好维护……我们把整个序列调过来,用(f1)表示(f)调过来后的序列,那么后半部分就可以写成(sum_{i = 0}^{n - j - 1} f1(n - i - j - 1) * g(j))

    那么前后两个式子都符合了卷积的形式,可以使用FFT求解。然后它问的每一个(E_i)相对应地就是每一个系数。

    看一下代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<map>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define fr friend inline
    #define y1 poj
    #define mp make_pair
    #define pr pair<int,int>
    #define fi first
    #define sc second
    #define pb push_back
    
    using namespace std;
    typedef long long ll;
    const int M = 200005;
    const int INF = 1000000009;
    const double eps = 1e-7;
    const double pi = acos(-1);
    const ll mod = 998244353;
    
    ll read()
    {
        ll ans = 0,op = 1;char ch = getchar();
        while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
        while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
        return ans * op;
    }
    
    struct Comp
    {
       double x,y;
       Comp(){}
       Comp(double px,double py){x = px,y = py;}
       fr Comp operator + (const Comp &a,const Comp &b) {return (Comp){a.x + b.x,a.y + b.y};}
       fr Comp operator - (const Comp &a,const Comp &b) {return (Comp){a.x - b.x,a.y - b.y};}
       fr Comp operator * (const Comp &a,const Comp &b) {return (Comp){a.x * b.x - a.y * b.y,a.y * b.x + a.x * b.y};}
    }f[M<<1],g[M<<1],f1[M<<1],kx,ky;
    
    int n,rev[M<<1],len = 1,L;
    double c[M<<1];
    
    void fft(Comp *a,int f)
    {
       rep(i,0,len-1) if(i < rev[i]) swap(a[i],a[rev[i]]);
       for(int i = 1;i < len;i <<= 1)
       {
          Comp omg1(cos(pi / i),f * sin(pi / i));
          for(int j = 0;j < len;j += (i << 1))
          {
         Comp omg(1,0);
         rep(k,0,i-1)
         {
            kx = a[j+k],ky = omg * a[j+k+i];
            a[j+k] = kx + ky,a[j+k+i] = kx - ky,omg = omg * omg1;
         }
          }
       }
    }
    
    int main()
    {
       n = read() - 1;
       rep(i,0,n)
       {
          scanf("%lf",&f[i].x),f1[n-i].x = f[i].x;
          if(i) g[i].x = 1.0 / double(i) / double(i);
       }
       while(len <= n << 1) len <<= 1,L++;
       rep(i,0,len-1) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (L-1));
       fft(f,1),fft(f1,1),fft(g,1);
       rep(i,0,len-1) f[i] = f[i] * g[i],f1[i] = f1[i] * g[i];
       fft(f,-1),fft(f1,-1);
       rep(i,0,n) c[i] = (f[i].x - f1[n - i].x) / len;
       rep(i,0,n) printf("%.3lf
    ",c[i]);
       return 0;
    }
    
    
  • 相关阅读:
    关于float和double类型能表示的数据范围和精度分析
    P2737 [USACO4.1]麦香牛块Beef McNuggets 数学题 + 放缩思想
    csu 1554: SG Value 思维题
    csu 1551: Longest Increasing Subsequence Again BIT + 思维
    Rasheda And The Zeriba Gym
    cpc,a wonderful concert
    hdu_3308 区间合并
    poj_3667线段树区间合并
    poj_2777线段树+位运算
    poj_3468,线段树成段更新
  • 原文地址:https://www.cnblogs.com/captain1/p/10111071.html
Copyright © 2011-2022 走看看