zoukankan      html  css  js  c++  java
  • 【BZOJ3527】【FFT】力

    【问题描述】
    给出n个数qi,给出Fj的定义如下:
    令Ei=Fi/qi。试求Ei。
    【输入格式】
    输入文件force.in包含一个整数n,接下来n行每行输入一个数,第i行表示qi。
    【输出格式】
    输出文件force.out有n行,第i行输出Ei。与标准答案误差不超过1e-2即可。
    【样例输入】
    5
    4006373.885184
    15375036.435759
    1717456.469144
    8514941.004912
    1410681.345880
    【样例输出】
    -16838672.693
    3439.793
    7509018.566
    4595686.886
    10903040.872
    【数据规模与约定】
    对于30%的数据,n≤1000。
    对于50%的数据,n≤60000。
    对于100%的数据,n≤100000,0<qi<1000000000。

    【分析】

    这道题...在省选里面相当裸了。

    自己把式子展开一下,发现跟卷积是类似的。

    于是对公式的前半部分做一下FFT,后半部分再做一下FFT,减一下,然后就是公式的样子了。

    感觉对FFT的理解更进一步了。

      1 /*
      2 宋代苏轼
      3 《临江仙·夜饮东坡醒复醉》
      4 夜饮东坡醒复醉,归来仿佛三更。家童鼻息已雷鸣。敲门都不应,倚杖听江声。
      5 长恨此身非我有,何时忘却营营。夜阑风静縠纹平。小舟从此逝,江海寄余生。  
      6 */
      7 #include <cstdio>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <cmath>
     11 #include <queue>
     12 #include <vector>
     13 #include <iostream>
     14 #include <string>
     15 #include <ctime>
     16 #define LOCAL
     17 const double Pi = acos(-1.0);
     18 const int MAXN = 100000 * 2 * 2 + 10;
     19 using namespace std;
     20 struct Num{
     21        double a, b;
     22        Num(double x = 0, double y = 0){a = x; b = y;}
     23        Num operator + (const Num &c){return Num(a + c.a, b + c.b);}
     24        Num operator - (const Num &c){return Num(a - c.a, b - c.b);}
     25        Num operator * (const Num &c){return Num(a * c.a - b * c.b, a * c.b + b * c.a);}
     26 }x1[MAXN], x2[MAXN];
     27 double data[MAXN], Ans[MAXN];
     28 int n;
     29 //交换成蝴蝶顺序 
     30 void change(Num *t, int len, int loglen){
     31      for (int i = 0; i < len; i++){
     32          int k = 0, x = i, tmp = loglen;
     33          while (tmp--) {k = (k<<1) + (x & 1);x >>= 1;}
     34          if (k < i) swap(t[k], t[i]);
     35      } 
     36      return;
     37 }
     38 //0为逆向 
     39 void FFT(Num *x, int len, int loglen, int type){
     40      if (type) change(x, len, loglen); 
     41      int t;//t代表长度
     42      t = (type ? 1 : (1<<loglen)); 
     43      for (int i = 0; i < loglen; i++){
     44          if (!type) t >>= 1;
     45          int l = 0, r = l + t;
     46          while (l < len){
     47                Num a, b;//临时变量
     48                Num tmp(1, 0), w(cos(Pi / t), (type ? 1 : -1) * sin(Pi / t)); 
     49                for (int j = l; j < l + t; j++){
     50                    if (type){
     51                       a = x[j];
     52                       b = x[j + t] * tmp;
     53                       x[j] = a + b;
     54                       x[j + t] = a - b;
     55                    }else{
     56                       a = x[j] + x[j + t];
     57                       b = (x[j] - x[j + t]) * tmp;
     58                       x[j] =  a;
     59                       x[j + t] = b;
     60                    }
     61                    tmp = tmp * w;
     62                }
     63                l = r + t;
     64                r = l + t; 
     65          }
     66          if (type) t <<= 1;
     67      }     
     68      if (!type){
     69         change(x, len, loglen);
     70         for (int i = 0; i < len; i++) x[i].a /= len;
     71      } 
     72 }
     73 void init(){
     74      memset(x1, 0, sizeof(x1));
     75      memset(x2, 0, sizeof(x2));
     76      int len = 0;
     77      while ((1 << len) < n) len++;
     78      len++;
     79      for (int i = 0; i < n; i++) x1[i] = Num(data[i], 0);
     80      for (int i = 1; i < n; i++) x2[i] = Num((double)1.0 / (double)(i * (double)i), 0);
     81      //for (int i = 1; i < n; i++) printf("%lf
    ", x2[i].a);
     82      
     83      FFT(x1, (1<<len), len, 1);
     84      FFT(x2, (1<<len), len, 1);
     85      for (int i = 0; i < (1 << len); i++) x1[i] = x1[i] * x2[i];
     86      FFT(x1, (1<<len), len, 0);
     87 }
     88 void debug(){
     89      int len = 0;
     90      scanf("%d", &n);
     91      while ((1<<len) <= (n << 1)) len++;
     92      for (int i = 0; i < n; i++) scanf("%lf", &x1[i].a);
     93      for (int i = 0; i < n; i++) scanf("%lf", &x2[i].a);
     94      FFT(x1, (1<<len), len, 1);
     95      FFT(x2, (1<<len), len, 1);
     96      for (int i = 0; i < (1 << len); i++) x1[i] = x1[i] * x2[i];
     97      FFT(x1, (1<<len), len, 0);
     98      for (int i = 0; i < n; i++) printf("%lf
    ", x1[i].a); 
     99 }
    100 
    101 int main() {
    102     
    103     scanf("%d", &n);
    104     for (int i = 0; i < n; i++) scanf("%lf", &data[i]);
    105     init();
    106     for (int i = 0; i < n; i++) Ans[i] = x1[i].a;
    107     reverse(data, data + n);
    108     init();
    109     for (int i = 0; i < n; i++) Ans[i] -= x1[n - 1 - i].a;
    110     for (int i = 0; i < n; i++) printf("%.3lf
    ", Ans[i]);
    111     //debug();
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    hibernate入门
    struts文件上传
    Struts的增删改查
    struts入门
    Maven配置以及环境搭配
    layui增删改查
    easyui三
    A
    C. Permutation Cycle
    E
  • 原文地址:https://www.cnblogs.com/hoskey/p/4377619.html
Copyright © 2011-2022 走看看