BZOJ 4909 [Sdoi2017]龙与地下城

DP

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
const double pi=acos(-1.0);
const int maxn=5000000;

int TT;
int n,m;

struct Comp{
double x,y;
inline Comp(double xx,double yy){
x=xx;y=yy;
}
inline Comp(){
x=y=0;
}
}g[maxn],a[maxn];
inline Comp operator + (Comp Z1,Comp Z2){
return Comp(Z1.x+Z2.x,Z1.y+Z2.y);
}
inline Comp operator - (Comp Z1,Comp Z2){
return Comp(Z1.x-Z2.x,Z1.y-Z2.y);
}
inline Comp operator * (Comp Z1,Comp Z2){
return Comp(Z1.x*Z2.x-Z1.y*Z2.y,Z1.x*Z2.y+Z1.y*Z2.x);
}
inline Comp operator * (Comp Z1,double k){
return Comp(Z1.x*k,Z1.y*k);
}
inline Comp operator / (Comp Z1,double k){
return Comp(Z1.x/k,Z1.y/k);
}

int rev[maxn],mi,len;

void FFT(Comp *arr,int n,int f){
for(register int i=0;i<n;++i)if(i<rev[i])swap(arr[i],arr[rev[i]]);

for(register int i=1;i<n;i<<=1){
int p=i+i;
Comp wn(cos(pi/i),f*sin(pi/i));
for(register int j=0;j<n;j+=p){
Comp w(1,0);
for(register int k=0;k<i;++k,w=w*wn){
Comp x=arr[j+k],y=arr[j+k+i]*w;
arr[j+k]=x+y;arr[j+k+i]=x-y;
}
}
}
if(f==-1)for(register int i=0;i<n;++i)arr[i]=arr[i]/n;
}

void Ksm(int p){
g[0].x=1;
FFT(g,len,1);FFT(a,len,1);
for(;p;p>>=1){
if(p&1){
for(register int i=0;i<len;++i)g[i]=g[i]*a[i];
}
for(register int i=0;i<len;++i)a[i]=a[i]*a[i];
}
FFT(g,len,-1);
}

double sum[maxn];

int main(){
scanf("%d",&TT);
while(TT--){
scanf("%d%d",&n,&m);
for(int i=0;i<maxn;++i){
g[i].x=g[i].y=a[i].x=a[i].y=0;
}
for(int i=0;i<n;++i)a[i].x=1.0/n;
for(len=1,mi=0;len<=(n-1)*m;len<<=1)mi++;
for(int i=0;i<len;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(mi-1));

Ksm(m);
sum[0]=g[0].x;
for(int i=1;i<=(n-1)*m;++i)sum[i]=sum[i-1]+g[i].x;
for(int t=1;t<=10;++t){
int l,r;
scanf("%d%d",&l,&r);
printf("%.10f\n",sum[r]-sum[l-1]);
}
}
return 0;
}


posted @ 2018-03-14 06:34  ws_zzy  阅读(160)  评论(0编辑  收藏  举报