【BZOJ】【2194】快速傅里叶之二

FFT

  c[k]=sigma a[i]*b[i-k] 这个形式不好搞……

  而我们熟悉的卷积的形式是这样的 c[k]=sigma a[i]*b[k-i]也就是【下标之和是定值】

  所以我们将a数组反转一下就可以卷积了=。=

 1 /**************************************************************
 2     Problem: 2194
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:2008 ms
 7     Memory:48148 kb
 8 ****************************************************************/
 9
10 //BZOJ 2194
11 #include<cmath>
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 using namespace std;
21 int getint(){
22     int v=0,sign=1; char ch=getchar();
23     while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();}
24     while(isdigit(ch))  {v=v*10+ch-‘0‘; ch=getchar();}
25     return v*sign;
26 }
27 /*******************template********************/
28 const int N=1000010;
29 const double pi=acos(-1);
30 struct comp{
31     double r,i;
32 //  comp(){}
33     comp(double _=0.0,double __=0.0) : r(_),i(__){}
34     comp operator + (const comp &b)const{return comp(r+b.r,i+b.i);}
35     comp operator - (const comp &b)const{return comp(r-b.r,i-b.i);}
36     comp operator * (const comp &b)const{return comp(r*b.r-i*b.i,r*b.i+i*b.r);}
37 }a[N],b[N],c[N];
38 void FFT(comp *a,int n,int type){
39     for(int i=1,j=0;i<n-1;++i){
40         for(int s=n;j^=s>>=1,~j&s;);
41         if(i<j) swap(a[i],a[j]);
42     }
43     for(int m=1;m<n;m<<=1){
44         double u=pi/m*type; comp wm(cos(u),sin(u));
45         for(int i=0;i<n;i+=(m<<1)){
46             comp w(1,0);
47             rep(j,m){
48                 comp &A=a[i+j+m], &B=a[i+j], t=w*A;
49                 A=B-t; B=B+t; w=w*wm;
50             }
51         }
52     }
53     if (type==-1) rep(i,n) a[i].r/=n;
54 }
55
56 int main(){
57     int n=getint();
58     rep(i,n){
59         a[n-i-1].r=getint();
60         b[i].r=getint();
61     }
62     int len=1;
63     for(len=1;len<=n<<1;len<<=1);
64     FFT(a,len,1); FFT(b,len,1);
65     rep(i,len) c[i]=a[i]*b[i];
66     FFT(c,len,-1);
67     D(i,n-1,0) printf("%d\n",int(c[i].r+0.5) );
68     return 0;
69 }

时间: 2024-08-26 05:31:32

【BZOJ】【2194】快速傅里叶之二的相关文章

【BZOJ 2194】 快速傅立叶之二

2194: 快速傅立叶之二 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 430 Solved: 240 [Submit][Status][Discuss] Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. Input 第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[

BZOJ 2194: 快速傅立叶之二

2194: 快速傅立叶之二 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1203  Solved: 699[Submit][Status][Discuss] Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. Input 第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a

【BZOJ 2194】2194: 快速傅立叶之二(FFT)

2194: 快速傅立叶之二 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1273  Solved: 745 Description 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. Input 第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i <

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

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

BZOJ 2194 快速傅立叶之二 快速傅里叶变换

题目大意:给定两个长度为n的序列a和b,求c[k]=Σa[i]*b[i-k] 这东西不是卷积的形式,因此我们将b数组反转,之后就是卷积的形式了 然后就愉♂悦地上FFT吧 #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 263000 #define PI 3.141592653589793

bzoj 2194: 快速傅立叶之二【NTT】

看别的blog好像我用了比较麻烦的方法-- (以下的n都--过 \[ c[i]=\sum_{j=i}^{n}a[i]*b[j-i] \] 设j=i+j \[ c[i]=\sum_{j=0}^{n-i}a[i+j]*b[i+j-i] \] \[ c[i]=\sum_{j=0}^{n-i}a[i+j]*b[j] \] 再设j=n-i-j \[ c[i]=\sum_{n-i-j}^{n-i}a[n-i-j+i]b[n-i-j] \] \[ n-i-j \geq 0 \Rightarrow j \leq

BZOJ.2194.快速傅立叶之二(FFT 卷积)

题目链接 \(Descripiton\) 给定\(A[\ ],B[\ ]\),求\[C[k]=\sum_{i=k}^{n-1}A[i]*B[i-k]\ (0\leq k<n)\] \(Solution\) (先令\(n=n-1\)) 首先往卷积上想.. \(i\)与\(i-k\)的差值是一定的,但是卷积的形式是\[C[k]=\sum_{i=1}^k A[i]*B[k-i]\] 即\(i\)与\(k-i\)的和是一定的. 于是考虑把一个数组反转一下,这里把\(B[\ ]\)反转,那么\[C[k]=

bzoj 1406: [AHOI2007]密码箱 二次剩餘

1406: [AHOI2007]密码箱 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 701  Solved: 396[Submit][Status] Description 在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能破解密码就能打开箱子,而箱子背面刻着的古代图标,就是对密码的提示.经过艰苦的破译,小可可发现,这些图标表示一个数以及这个数与密码的关系.假设这个数是n,密码为x,那么可以得到如下表述: 密码

bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)5.查询k在区间内的后继(后继定义为大于x,且最小的数) Input 第一行两个数 n,