小笨的蓄水池
1.牛客练习赛872.牛客小白月赛373.牛客IOI周赛28-普及组4.牛客竞赛数据结构专题班树状数组、线段树练习题
5.小笨的蓄水池
6.牛客周赛 Round 697.牛客周赛 Round 718.牛客周赛 Round 729.牛客周赛 Round 7310.2025牛客寒假算法基础集训营111.2025牛客寒假算法基础集训营212.2025牛客寒假算法基础集训营313.2025牛客寒假算法基础集训营414.2025牛客寒假算法基础集训营515.2025牛客寒假算法基础集训营616.牛客寒假训练营赛后总结17.牛客小白月赛11018.牛客周赛 Round 8219.牛客周赛 Round 84(选讲题目描述
小苯有 ( n ) 个水池,编号从 1 到 ( n ),每个水池中有一定的水量 ( )。水池之间有隔板,初始状态下这些隔板将水池隔开。
小苯需要进行两种操作:
移除隔板:操作格式为 1 l r,表示将第 ( l ) 个水池和第 ( r ) 个水池之间的所有隔板移除。这意味着在这个范围内的水池将会合并,水量会变成这些水池水量的平均值。
查询水量:操作格式为 2 i,表示查询第 ( i ) 个水池当前的水量。如果该水池的隔板已经被移除,它的水量将是合并后的平均值。
因此,题目的核心在于处理水池之间的隔板移除和水量查询,确保在移除隔板后能够正确计算和返回水量。
思路
这种数据的处理,没有寻常的数据结构处理,但是,这种区间合并的操作,与并查集非常类似
并查集的思想在于,两颗树之间的合并,而这里的区间亦可以进行类似的操作
移除隔板后,就将相邻的区间合并(合并相邻两颗子树),查询时就查询区间被合并到哪个区间了(类似于父节点)
CODE
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
struct node{
int l,r,cnt;
double sum;
}a[maxn];
int f[maxn];
int n,m;
int find(int x){
if(x!=f[x]) return f[x]=find(f[x]);
return x;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%lf",&a[i].sum);
a[i].l=a[i].r=i;
a[i].cnt=1;f[i]=i;
}
while(m--){
int op;scanf("%d",&op);
if(op==1){
int x,y;scanf("%d %d",&x,&y);
double ans=0;
for(int i=a[f[x]].r+1;i<=a[f[y]].l;++i){
if(find(x)==find(i)) continue;//同属一区间
int fx=find(x),fi=find(i);
f[fi]=fx;//合并
a[fx].sum+=a[fi].sum;
a[fx].cnt+=a[fi].cnt;
a[fx].l=min(a[fx].l,a[fi].l);
a[fx].r=max(a[fx].r,a[fi].r);
}
}
else{
int x;scanf("%d",&x);
printf("%.12f\n",a[find(x)].sum*1.0/a[find(x)].cnt);//输出平均值
}
}
return 0;
}
本文作者:归游
本文链接:https://www.cnblogs.com/guiyou/p/18526247
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步