BNUOJ 27935 我爱背单词(FFT)

2 篇文章 0 订阅
1 篇文章 0 订阅

题目链接:点击打开链接

思路:

该题暴力当然可以过,   如果数据量加大,  我们还有一种nlogn的算法:FFT

仔细观察这个复习单词量的累加方式可以发现, 这是一个卷积, 可以用FFT加速算法。

细节参见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <ctime>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const double eps = 1e-6;
const double PI = acos(-1);
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
// & 0x7FFFFFFF
const int seed = 131;
const ll INF64 = ll(1e18);
const int maxn = 4000 + 10;
int T,n,m,b[maxn], a[maxn];
struct Complex {
    double x, y; // 实部和虚部 x + yi
    Complex(double _x = 0.0, double _y = 0.0) {
        x = _x;
        y = _y;
    }
    Complex operator +(const Complex &b) const {
        return Complex(x + b.x, y + b.y);
    }
    Complex operator -(const Complex &b) const {
        return Complex(x - b.x, y - b.y);
    }
    Complex operator *(const Complex &b) const {
        return Complex(x*b.x-y*b.y, x*b.y+y*b.x);
    }
};
void change(Complex y[], int len) {
    int i, j, k;
    for(i = 1, j = len/2; i < len-1; i++) {
        if(i < j) swap(y[i], y[j]);
        k = len/2;
        while(j >= k) { j -= k; k /= 2; }
        if(j < k) j += k;
    }
}
void fft(Complex y[], int len, int on) {
    change(y, len);
    for(int h = 2; h <= len; h <<= 1) {
        Complex wn(cos(-on*2*PI/h), sin(-on*2*PI/h));
        for(int j = 0; j < len; j += h) {
            Complex w(1, 0);
            for(int k = j; k < j + h/2; k++) {
                Complex u = y[k];
                Complex t = w*y[k+h/2];
                y[k] = u + t;
                y[k+h/2] = u - t;
                w = w * wn;
            }
        }
    }
    if(on == -1) {
        for(int i = 0; i < len; i++) y[i].x /= len;
    }
}
Complex x1[maxn], x2[maxn], ans[maxn];
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 0; i < n; i++) scanf("%d", &a[i]);
        scanf("%d", &m);
        int len1 = n, len2 = 0, len = 1;
        for(int i = 0; i < m; i++) scanf("%d", &b[i]), len2 = max(len2, b[i]);
        while(len < len1 * 2 || len < len2 * 2) len <<= 1;
        for(int i = 0; i < len2; i++) x2[i] = Complex(0, 0);
        for(int i = 0; i < n; i++) x1[i] = Complex(a[i], 0);
        for(int i = 0; i < m; i++) x2[b[i]-1] = Complex(1, 0);
        for(int i = len1; i < len; i++) x1[i] = Complex(0, 0);
        for(int i = len2; i < len; i++) x2[i] = Complex(0, 0);
        fft(x1, len, 1);
        fft(x2, len, 1);
        for(int i = 0; i < len; i++) ans[i] = x1[i] * x2[i];
        fft(ans, len, -1);
        for(int i = 0; i < n; i++) ans[i].x += a[i];
        len = len1 + len2 - 1;
        int q; scanf("%d", &q);
        while(q--) {
            int id;
            scanf("%d", &id);
            if(id > len) printf("0\n");
            else printf("%d\n", (int)round(ans[id-1].x));
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
delphi源码迷你背单词源码:内涵大量词典,可以背几乎所有的单词!! CHINESE.DAT config.ini DFHGWPRN.TTF DictStar.ttf ENGLISH.DAT GMAT词汇.dst GRE 词频表字母序(zm).dst GRE 词频表词频序(zm).dst GRE必背.dst GRE词汇.dst GRE逆序.dst list.txt MBA词汇(zm).dst PP2 中的单词(zm).dst PP2 填空词汇(zm).dst PP2 类比反义词汇(zm).dst wordrain dir.txt 上教精读第一册.dst 上教精读第二册.dst 上教精读第五册.dst 上教精读第六册.dst 分类词库.dst 初中英语第一册.dst 初中英语第三册.dst 初中英语第二册.dst 初中英语第五册.dst 初中英语第六册.dst 初中英语第四册.dst 剑桥少儿英语第一级上.dst 剑桥少儿英语第一级下.dst 剑桥少儿英语第三级上.dst 剑桥少儿英语第三级下.dst 剑桥少儿英语第二级上.dst 剑桥少儿英语第二级下.dst 医学英语第一册.dst 医学英语第三册.dst 医学英语第二册.dst 商务英语词汇.dst 商务词汇.dst 外贸英语一.dst 外贸英语三.dst 外贸英语二.dst 外贸英语四.dst 大学英语5级6级常用词组.dst 大学英语六级词汇.dst 大学英语四级词汇.dst 大学英语自学教程上.dst 大学英语自学教程下.dst 大学词组.dst 太傻单词.dst 太傻单词7月精简版(zm).dst 小学英语第一册.dst 小学英语第三册.dst 小学英语第二册.dst 小学英语第四册.dst 常用前后缀.dst 懒人单词(zm修正).dst 托福词汇(zm).dst 托福词汇.dst 托福词组.dst 新概念英语第一册.dst 新概念英语第三册.dst 新概念英语第二册.dst 新概念英语第四册.dst 新编初中英语第一册.dst 新编初中英语第三册.dst 新编初中英语第二册.dst 新编小学英语第一册.dst 新编小学英语第三册.dst 新编小学英语第二册.dst 新编小学英语第五册.dst 新编小学英语第六册.dst 新编小学英语第四册.dst 新编高中英语第一册必修本下.dst 新编高中英语第三册实验本上.dst 新编高中英语第三册实验本下.dst 新编高中英语第三册必修本上.dst 新编高中英语第二册实验本上.dst 新编高中英语第二册实验本下.dst 新编高中英语第二册必修本上.dst 新编高中英语第二册必修本下.dst 李扬疯狂英语三百六十五句.dst 研究生入学词汇.dst 研究生入学词组.dst 职称英语等级考试A.dst 职称英语等级考试B.dst 职称英语等级考试C.dst 计算机词汇.dst 许国璋英语第一册.dst 许国璋英语第三册.dst 许国璋英语第二册.dst 许国璋英语第四册.dst 词根记忆法.dst 金融英语(zm).dst 雅思英语(zm修正).dst 雅思英语完整版(zm).dst 高中英语第一册.dst 高中英语第三册.dst 高中英语第二册.dst 高教自学考试英语.dst

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值