BZOJ 4909 [Sdoi2017]龙与地下城

题解:

自适应Simpson积分

刘坑

不会正态分布

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  阅读(180)  评论(0编辑  收藏  举报