ECF R9(632E) & FFT

Description:

  上一篇blog.

Solution:

  同样我们可以用fft来做...就像上次写的那道3-idoit一样,对a做k次卷积就好了.

  同样有许多需要注意的地方:我们只是判断可行性,所以为了保证精度如果f大于1就把它变成1; 对于长度也可以慢慢倍增,可以优化复杂度就是写起来麻烦.

  

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].r /= len;
}
const int maxn = 2e6+5;
complex x1[maxn], x2[maxn];
int a[maxn], b[maxn];
void cal(int *a, int *b, int &lena, int &lenb) {
    int len = 1;
    while(len<lena+lenb)
        len<<=1;
    for(int i = 0; i<=lenb; i++) {
        x1[i] = complex(b[i], 0);
    }
    for(int i = lenb+1; i<len; i++)
        x1[i] = complex(0, 0);
    for(int i = 0; i<=lena; i++) {
        x2[i] = complex(a[i], 0);
    }
    for(int i = lena+1; i<len; i++)
        x2[i] = complex(0, 0);
    fft(x1, len, 1);
    fft(x2, len, 1);
    for(int i = 0; i<len; i++)
        x1[i] = x1[i]*x2[i];
    fft(x1, len, -1);
    for(int i = 0; i<=lena+lenb; i++)
        b[i] = (int)(x1[i].r+0.5);
    for(int i = 0; i<=lena+lenb; i++)
        if(b[i]>0)
            b[i] = 1;
    lenb += lena;
}
int main()
{
    int n, k, x;
    cin>>n>>k;
    for(int i = 0; i<n; i++) {
        scanf("%d", &x);
        a[x]++;
    }
    b[0] = 1;
    int lena = 1000, lenb = 0;
    while(k) {
        if(k&1) {
            cal(a, b, lena, lenb);
        }
        if(k>1) {
            cal(a, a, lena, lena);
        }
        k>>=1;
    }
    for(int i = 0; i<=lena+lenb; i++) {
        if(b[i]) {
            printf("%d ", i);
        }
    }
    cout<<endl;
    return 0;
}
时间: 2024-11-09 02:46:16

ECF R9(632E) & FFT的相关文章

ECF R9(632E) &amp; DP

Description: 给你$n$个数可以任取$k$个(可重复取),输出所有可能的和. $n \leq 1000,a_i \leq 1000$ Solution: 好神的DP,我们排序后把每个数都减去第一个,那么第一个就变成0,任意取不足k次的j次都是合法的-----多余的可以用第一个补上.不过感觉复杂度不太对啊...CF也真是快啊... for(i=0;i<=1000000;i++)dp[i]=inf; dp[0]=0; for(j=0;j<=1000000;j++){ for(i=1;i

XJTUOJ wmq的A&#215;B Problem FFT

wmq的A×B Problem 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 3000ms   内存限制: 512M 描述 这是一个非常简单的问题. wmq如今开始学习乘法了!他为了训练自己的乘法计算能力,写出了n个整数,并且对每两个数a,b都求出了它们的乘积a×b.现在他想知道,在求出的n(n−1)2个乘积中,除以给定的质数m余数为k(0≤k<m)的有多少个. 输入 第一行为测试数据的组数. 对于每组测试数据,第一行为2个正整数n,

对AM信号FFT的matlab仿真

普通调幅波AM的频谱,大信号包络检波频谱分析 u(t)=Ucm(1+macos ?t)cos ?ct ma称为调幅系数 它的频谱由载波,上下边频组成 , 包络检波中二极管截去负半周再用电容低通滤波,可以得到基带信号,那么,截去负半周后的AM信号必定包含基带信号的频谱.我们可以通过matlab来验证. %已知基带信号为1hz,载波为64hz,调制系数ma=0.3,采样频率1024hz,FFT变换区间N为2048 clear; fs=1024; f=1; %1hz基带信号 fc=64; %64hz载

多项式FFT相关模板

自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <algorithm> #include <vector> using namespace std; #de

多项式艺术:浅谈FFT和NTT算法(未完待续)

什么是多项式? 百度百科说:“由若干个单项式相加组成的代数式叫做多项式.多项式中每个单项式叫做多项式的项,这些单项式中的最高次数,就是这个多项式的次数.” 也就是说,形如的式子,就叫做多项式.这样的式子,也能写作.很显然,多项式加上(或是减上)多项式也是多项式,复杂度是的.但是,如果多项式想要乘上一个多项式,那么也可以,最简单的方法却是的. 不过,FFT算法会告诉你,就够了. 多项式乘法 我们说的,多项式想要乘上一个多项式,那就是多项式乘法,人称“卷积”.我们方才所看到的,被称为多项式的“系数表

FFT模板(From MG)

1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 struct cp{double x,y;}; 6 int n1,n2,n,m; 7 double pi=acos(-1); 8 cp a[500010],b[500010],cur[500010]; 9 cp operator *(cp x,cp y){return (cp){x.x*y.x-x.y*y

Bzoj2179 FFT快速傅立叶

Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3079  Solved: 1581 Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output 12 数据范围: n<=60000 HINT Source FFT FFT真

BZOJ 2194 快速傅立叶之二 ——FFT

[题目分析] 咦,这不是卷积裸题. 敲敲敲,结果样例也没过. 看看看,卧槽i和k怎么反了. 艹艹艹,把B数组取个反. 靠靠靠,怎么全是零. 算算算,最终的取值范围算错了. 交交交,总算是A掉了. [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <map> #include <set> #include <

BZOJ 2179 FFT快速傅立叶 ——FFT

[题目分析] 快速傅里叶变换用于高精度乘法. 其实本质就是循环卷积的计算,也就是多项式的乘法. 两次蝴蝶变换. 二进制取反化递归为迭代. 单位根的巧妙取值,是的复杂度成为了nlogn 范德蒙矩阵计算逆矩阵又减轻了拉格朗日插值法的复杂度. 十分神奇. [代码] #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #includ