【JZOJ3617】【ZJOI2014】力
╰( ̄▽ ̄)╭
对于100%的数据,
(⊙ ▽ ⊙)
令
设
显然
像
当满足
这样的形式时,可以利用快速傅里叶变换:
设多项式
多项式
则多项式
( ̄~ ̄)
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<string.h>
#define ll long long
using namespace std;
const char* fin="ex3617.in";
const char* fout="ex3617.out";
const int inf=0x7fffffff;
const int maxn=500007;
const double pi=acos(-1);
struct Z{
double x,y;
Z(double _x=0,double _y=0){x=_x;y=_y;}
Z operator +(const Z &a){return Z(x+a.x,y+a.y);}
Z operator -(const Z &a){return Z(x-a.x,y-a.y);}
Z operator *(const Z &a){return Z(x*a.x-y*a.y,x*a.y+y*a.x);}
}a[maxn],b[maxn],c[maxn],d[maxn];
int n,m,i,j,k,r[maxn];
void fft(Z *a,int sig){
int i,j,k;
for (i=0;i<n;i++) if (r[i]<i) swap(a[r[i]],a[i]);
for (i=2;i<=n;i<<=1){
int ha=i/2;
for (j=0;j<ha;j++){
Z w(cos(j*pi*sig/ha),sin(j*pi*sig/ha));
for (k=j;k<n;k+=i){
Z u=a[k],v=w*a[k+ha];
a[k]=u+v;
a[k+ha]=u-v;
}
}
}
}
int main(){
scanf("%d",&n);
for (i=0;i<n;i++){
scanf("%lf",&a[i].x);
c[n-1-i].x=a[i].x;
}
for (i=1;i<n;i++) b[i]=1.0/i/i;
m=n;
k=0;
for (n=1;n<m<<1;n<<=1) k++;
for (i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(k-1));
fft(a,1);
fft(c,1);
fft(b,1);
for (i=0;i<n;i++) a[i]=a[i]*b[i];
for (i=0;i<n;i++) c[i]=c[i]*b[i];
fft(a,-1);
fft(c,-1);
for (i=0;i<m;i++) printf("%lf\n",a[i].x/n-c[m-i-1].x/n);
return 0;
}
(⊙v⊙)
1.
for (i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(k-1));
这是一行很强的代码,可以用于求出:二进制数
具体地,
采用递推的形式,
实质是
2.WARNING
最后的结果一定要