【2019北京集训测试赛(十三)】数据(sj) 冷静分析
题目大意:给你一个代表区间[1,n]的线段树,问你随机访问区间[1,n]中的一个子区间,覆盖到的线段树节点个数的期望(需要乘上n(n−1)2后输出)。
数据范围:n≤1018
貌似各位的做法都非常优秀,代码也非常短,那么我来讲一个垃圾做法:
我们设f[i]表示一个构建出[1,i]的线段树,随机访问一个子区间覆盖线段树节点个数的期望(为方便处理,乘上了i(i−1)2)。
显然f[n]就是答案。
我们再设fl[j][i]表示一棵[1,i]的线段树,从左边往右,覆盖了j个线段树节点的方案数。
同理我们处理出fr[j][i]
我们发现:当j>1时,选择覆盖j个点,这j个点显然不会包含整个区间。
我们设L=⌈i2⌉ ,R=⌊i2⌋
那么有fl[i][j]=fl[j][L]+fl[j−1][r]−[j≤2],fr[i][j]同理。
我们考虑f[i]要怎么求。
不难发现,f[i]有四种构成方式:只选择了左/右端的区间,两边都选了,恰好选择了根节点。
只选择一侧的显然是f[L]+f[R],恰好选择根节点的贡献显然为1。
对于两边都选的情况,我们通过枚举fr[][L]和fl[][R],简单地乘起来,再乘上总共选择的节点个数,就可以了。
综上,则有:
f[i]=1+f[L]+f[R]+dep1∑v1=1dep2∑v2=1(v1+v2)×(fr[v1][L]×fl[v2][R]−[v1=1,v2=1])
其中,dep1,dep2表示左右两颗子树的最大深度。
在求解过程中,我们暴力往下递归,我们需要特判i=1,2,3的情况,然后就可以了。
这个复杂度比较垃圾,应该是O(log3 n)的。
场上真刺激,最后十分钟调处来了23333
1 #include<bits/stdc++.h> 2 #define M 998244353 3 #define L long long 4 #define MOD 998244353 5 using namespace std; 6 7 map<L,L> f,fl[100],fr[100],vis,up; 8 9 void solve(L i){ 10 if(vis[i]) return; 11 if(i==1){ 12 f[i]=fl[1][i]=fr[1][i]=vis[i]=1; 13 fl[0][i]=fr[0][i]=up[i]=1; 14 return; 15 } 16 if(i==2){ 17 f[i]=3; 18 fl[1][i]=fr[1][i]=2; 19 fl[0][i]=fr[0][i]=1; 20 vis[i]=up[i]=1; 21 return; 22 } 23 if(i==3){ 24 f[i]=7; 25 fl[1][i]=3; fr[1][i]=2; 26 fl[0][i]=fr[0][i]=1; 27 vis[i]=1; up[i]=2; 28 fr[2][i]=1; 29 return; 30 } 31 L l=(i+1)>>1,r=i-l; 32 solve(l); solve(r); 33 int upl=up[l],upr=up[r],UP=max(upl,upr)+1; up[i]=UP; 34 vis[i]=1; 35 L sum=f[l]+f[r]; 36 for(int v1=1;v1<=upl;v1++) 37 for(int v2=1;v2<=upr;v2++){ 38 sum=(sum+1LL*(v1+v2)*(fr[v1][l]*fl[v2][r]%MOD+MOD-(v1==1&&v2==1)))%MOD; 39 } 40 // for(int v1=0;v1<=upl;v1++) sum=(sum-fr[v1][l])%MOD; 41 // for(int v2=0;v2<=upr;v2++) sum=(sum-fl[v2][r])%MOD; 42 f[i]=(sum+1)%MOD; 43 for(int j=1;j<=UP;j++){ 44 fl[j][i]=(fl[j][l]+fl[j-1][r]-(j<=2)+MOD)%MOD; 45 int x=fl[j][i]; 46 fr[j][i]=(fr[j-1][l]+fr[j][r]-(j<=2)+MOD)%MOD; 47 int y=fr[j][i]; 48 x++; 49 } 50 // cout<<fr[2][3]<<endl; 51 fl[0][i]=fr[0][i]=1; 52 fl[1][i]++; fr[1][i]++; 53 } 54 55 int main(){ 56 L n;cin>>n; 57 solve(n); 58 cout<<f[n]<<endl; 59 }
【推荐】国内首个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帮你做增删改查!!