题目大意:
假设高斯定理在 m 维空间成立
已知 m 维空间所有整点电荷 aj
给出 m 维空间下 x,y 两点距离公式
以及x点在y点引发的电势公式
T≤51≤m≤18n≤3∗105
时限 7s
考试的时候看这道题的时候 感觉这道题根本不可做啊???
部分分很友好啊?除了一个5分的点 其他我都不会。。
看完题解之后整个人都不好了。。
然后我用了一个下午来调试 压常
其实 上面那个式子就是卷积的形式 只不过 这个是m维卷积。。。(做毛线啊
好吧 m维卷积大家都会喜闻乐见的 FWT ?
平常的FWT一般都是每一维大小为2 的情况 当大于2的时候我们可以直接上DFT
然后我们会发现这个循环卷积也不好处理
怎么办呢?
将DFT的式子拆成卷积形式 然后FFT优化卷积之后即可得出
即 Bluestein′sAlgorithm
时间复杂度 O(nlog2n)
注意常数很大 所以不得不不预处理单位根 以及一些黑科技
#include
#include
#include
#include
#include
#include
using namespace std;
#define ld double
ld Sin[20],Cos[20];
struct com
{
ld a,b;
com(){}
com(ld a,ld b):a(a),b(b){}
friend com operator +(com a,com b){return com(a.a+b.a,a.b+b.b);}
friend com operator -(com a,com b){return com(a.a-b.a,a.b-b.b);}
friend com operator *(com a,com b){return com(a.a*b.a-a.b*b.b,a.b*b.a+a.a*b.b);}
friend com operator /(com a,ld b){return com(a.a/b,a.b/b);}
friend com operator *(com a,ld b){return com(a.a*b,a.b*b);}
};
const
ld pi=acos(-1);
int rev[2200005];
void FFT(com *a,int n,int fl)
{
int Len=1<for(int i=0;i>1]>>1)|((i&1)<1);
for(int i=0;iif(rev[i]>i)swap(a[rev[i]],a[i]);
for(int p=0,i=1;i*=2,p++)
{
com w=com(Cos[p],fl*Sin[p]);
for(int j=0;j2*i)
{
com w0=com(1,0);
for(int k=0;kx=a[j+k],y=w0*a[i+j+k];
a[j+k]=x+y;
a[j+k+i]=x-y;
w0=w0*w;
}
}
}
if(fl==-1)
for(int i=0;i2200005],b[2200005];
int C;
ld SIN[2200005],COS[2200005];
void DFT(com* a,int d,int n,int fl)
{
int N=1;
for(;(1<3*n);N++);
int P=C/2/n,Nf=2*n;
for(int i=0;i<2*n;i++)
b[i]=com(COS[i*1ll*i%Nf*P],fl*SIN[i*1ll*i%Nf*P]);
for(int i=0;i*1ll*i%Nf*P],-fl*SIN[i*1ll*i%Nf*P])*a[i*d];
if(n<=50)
{
for(int i=n;i<2*n;i++)
{
int pos=i-n;
pos*=d;
a[pos]=com(0,0);
for(int j=0;j<=i;j++)
a[pos]=a[pos]+b[i-j]*c[j];
}
}
else
{
for(int i=0;icos(pi/(1<sin(pi/(1<1);
FFT(c,N,1);
for(int i=0;i<(1<*c[i];
FFT(b,N,-1);
for(int i=0;i*d]=b[i+n];
}
for(int i=0;i*d]=a[i*d]*com(COS[i*1ll*i%Nf*P],-fl*SIN[i*1ll*i%Nf*P]);
if(fl==-1)
for(int i=0;i*d]=a[i*d]/n;
for(int i=0;i<(1<0,0);
}
int s[2200005];
void FWT(com* a,int n,int m,int fl)
{
int len=1;
for(int i=0;i<m;len*=s[i++])
for(int j=0;j*s[i])
for(int k=0;ks[i],fl);
}
com Da[2200005];
int no[2200005];
bool cmp(int a,int b)
{
return Da[a].a>Da[b].a;
}
int main()
{
freopen("anarchy.in","r",stdin);
freopen("anarchy.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
int m,n=1;
scanf("%d",&m);
for(int i=0;i<m;i++)scanf("%d",s+i),n*=s[i];C=n;
for(int i=0;iint t;
scanf("%d",&t);
Da[i].a=t;
Da[i].b=1;
for(int t=i,j=0;j<m;t/=s[j++])
Da[i].b*=t%s[j]+1;
Da[i].b=powl(Da[i].b,2.0/m);
Da[i].b/=2.*m;
Da[i]=com(Da[i].a+Da[i].b,Da[i].a-Da[i].b);
}
C*=2;
for(int i=0;i<2*n;i++)
SIN[i]=sin(2*pi/2/n*i),COS[i]=cos(2*i*pi/2/n);
FWT(Da,n,m,1);
for(int i=0;i*Da[i];
FWT(Da,n,m,-1);
for(int i=0;ino[i]=i;
sort(no,no+n,cmp);
for(int i=0;i100);i++)
printf("%.9f ",Da[no[i]].a/4);
puts("");
}
return 0;
}