【xsy2332】Randomized Binary Search Tree DP+FFT
题目大意:给你一个[0,1]之间等概率随机序列,你需要把这个序列插入到一棵treap中,问这棵treap的期望深度,请对于[1,n]中的每个深度分别输出它的概率(实数,保留五位小数)。
treap的优先级之也是在[0,1]中等概率随机出来的。
ps:这个[0,1]的随机非常niubi,任意一个[0,1]间的实数被选中的概率是0
这一题有一个很特殊的性质:两个序列都是等概率随机出来的。
在没有相同数的情况下,我们发现treap最终的形态跟数值插入的顺序是没有关系的。
假如我们将整个序列排序,我们会发现这些元素被treap分配的优先级,是一个(随机的)随机数序列。
treap的形状等价于优先级序列的笛卡尔树。
所以我们可以列出一个dp:设f[i][j]表示j个点构成的笛卡尔树深度不大于i的概率。
考虑到每个点的值都是随机的,则有:f[i][j]=1jj∑k=1f[i−1][k−1]×f[i−1][j−k]
直接转移的概率显然是O(n3)的。
我们发现,概率会集中在笛卡尔树期望深度附近,所以实际上并不需要DP到f[n][],我们大概率只需要dp到f[50][]即可满足精度要求(剩下的都是0)
然后,发现上面的式子是一个卷积,我们可以用FFT加速转移。
所以最终的复杂度就变成了O(Anlog n)
1 #include<bits/stdc++.h> 2 #define M (1<<16) 3 #define PI acos(-1) 4 using namespace std; 5 6 struct cp{ 7 double r,i; cp(){i=r=0;} 8 cp(double R,double I){r=R; i=I;} 9 friend cp operator +(cp a,cp b){return cp(a.r+b.r,a.i+b.i);} 10 friend cp operator -(cp a,cp b){return cp(a.r-b.r,a.i-b.i);} 11 friend cp operator *(cp a,cp b){return cp(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);} 12 friend cp operator /(cp a,double b){return cp(a.r/b,a.i/b);} 13 }a[M]; 14 15 void change(cp a[],int n){ 16 for(int i=0,j=0;i<n-1;i++){ 17 if(i<j) swap(a[i],a[j]); 18 int k=n>>1; 19 while(j>=k) j-=k,k>>=1; 20 j+=k; 21 } 22 } 23 void FFT(cp a[],int n,int on){ 24 change(a,n); 25 for(int h=2;h<=n;h<<=1){ 26 cp wn=cp(cos(2*PI/h),sin(2*PI*on/h)); 27 for(int j=0;j<n;j+=h){ 28 cp w=cp(1,0); 29 for(int k=j;k<j+(h>>1);k++){ 30 cp u=a[k],t=a[k+(h>>1)]*w; 31 a[k]=u+t; a[k+(h>>1)]=u-t; 32 w=w*wn; 33 } 34 } 35 } 36 if(on==-1) 37 for(int i=0;i<n;i++) a[i]=a[i]/n; 38 } 39 40 int main(){ 41 int n; scanf("%d",&n); double las=0; 42 int len=1; for(;len<=n*2;len<<=1); 43 a[0]=cp(1,0); 44 for(int hh=1;hh<=min(n,50);hh++){ 45 //if(las<1e-5){printf("0\n"); continue;} 46 FFT(a,len,1); 47 for(int i=0;i<len;i++) a[i]=a[i]*a[i]; 48 FFT(a,len,-1); 49 for(int i=n;i<len;i++) a[i]=cp(0,0); 50 for(int i=n;i;i--) a[i]=a[i-1]/i; a[0]=cp(1,0); 51 printf("%.10lf\n",a[n].r-las); 52 las=a[n].r; 53 } 54 for(int i=min(n,50)+1;i<=n;i++) printf("%.10lf\n",0); 55 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!