[HDU5604]守鹤之砂
来源:互联网 发布:新业汽修软件数据服务 编辑:程序博客网 时间:2024/04/28 12:08
题目描述
当初,我爱罗作为“祭品之力”,为了控制体内“一尾”的力量,他开始了无休止的修炼。
作为一个刚入门的忍者,我爱罗先是要学会控制“一尾”守鹤之砂,第一步当然是要学会合并砂团啦,当然了,肯定不是盲目的合并,所以他给一开始的n个砂团从1到n编号,然后,每次合并,他会选择两个砂团u和v,将u所在的砂团集合与v所在的砂团集合合并,然后他对合并后的集合进行以下计算:
将所有砂团的编号取出来,假设有k个砂团,编号分别为a[1],a[2]..a[k],假设一开始所有数都在其数轴上对应的位置,我们要做的是让最大的数和最小的数相遇,并求相遇最小时间。
我们这样操作这些数:
每次操作可以选择两个数轴上相邻数交换,多个操作可以同时进行,但不能对一个数同时进行两个交换操作。
交换时间就是两个数在数轴上的距离,因为每个数一个单位时间移动一个单位距离,一个交换操作中途两个数不能停下来,不能改变交换对象,直到两个数交换了位置。
当最小的数和最大的数走到了相邻位置时,他们相遇的时间就是距离/2,因为交换中途就会相遇。
相遇完后,数的位置恢复原状。
下面举一个例子:
1..4……11….16..19
我们要让1和19相遇
首先让1、4和16、19交换,他们可以同时进行,而且恰好同时结束了。用时3个单位,然后变成下面这样:
4..1……11….19..16
接下来有两种情况:
A方案:
先让1和11先交换,19不动,那么用时7个单位,然后变成下面这样:
4..11……1….19..16
再交换1和19,用时2.5个单位。
加起来是这样的:3+7+2.5=12.5
B方案:
先让11和19交换,1不动,那么用时五个单位,且变成下面这样:
4..1……19….11..16
再用1和19交换,所用的时间是3.5个单位。
加起来是这样的:3+5+3.5=11.5
很明显B方案更优。
所以最少用时是11.5。
看样子大家都读懂题意了。
现在我爱罗已经是风影了,为了考验你这个新晋的上忍,他决定以当初的难题来考验你。
线段树合并
考虑如何求一个序列a1..n的答案
对于所有j求min(max(aj-a1,an-aj+1)+(aj+1-aj)/2)
把max外面的加进去,设mid=(aj+1+aj)/2,则变成max(mid-a1,an-mid)
于是我们分类讨论mid-a1>an-mid和mid-a1<=an-mid的两种情况,于是用线段树维护。
区间维护:
个数,最大最小值,相邻两个数相加的最大最小值
信息合并自己脑补,查询也很简单,详见代码。
#include<cstdio> #include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef double db;const int maxn=50000+10,maxtot=maxn*20;int root[maxn],left[maxtot],right[maxtot],num[maxtot],sum[maxtot],num2[maxtot],sum2[maxtot],cnt[maxtot];//num min sum maxint fa[maxn];int i,j,k,l,t,n,m,tot,ca;db ans,now;int getfa(int x){ return fa[x]?fa[x]=getfa(fa[x]):x;}int build(int &x,int l,int r,int wz){ x=++tot; if (l==r){ cnt[x]=1; num[x]=sum[x]=l; num2[x]=1000000; sum2[x]=0; return x; } int mid=(l+r)/2; if (wz<=mid) build(left[x],l,mid,wz);else build(right[x],mid+1,r,wz); cnt[x]=1; num[x]=sum[x]=sum[left[x]]+sum[right[x]]; num2[x]=1000000; sum2[x]=0; return x;}int merge(int a,int b,int l,int r){ if (!a||!b) return a+b; int mid=(l+r)/2; left[a]=merge(left[a],left[b],l,mid); right[a]=merge(right[a],right[b],mid+1,r); cnt[a]=cnt[left[a]]+cnt[right[a]]; num[a]=min(num[left[a]],num[right[a]]); sum[a]=max(sum[left[a]],sum[right[a]]); num2[a]=min(num2[left[a]],num2[right[a]]); if (cnt[left[a]]&&cnt[right[a]]) num2[a]=min(num2[a],sum[left[a]]+num[right[a]]); sum2[a]=max(sum2[left[a]],sum2[right[a]]); if (cnt[left[a]]&&cnt[right[a]]) sum2[a]=max(sum2[a],sum[left[a]]+num[right[a]]); return a;}int find(int p,int l,int r,int v){ if (cnt[p]<2) return 1000000; if (cnt[p]==2) return num[p]+sum[p]; int mid=(l+r)/2; if (cnt[left[p]]>1&&sum2[left[p]]>=v) return find(left[p],l,mid,v); else if (cnt[left[p]]&&cnt[right[p]]&&sum[left[p]]+num[right[p]]>=v) return sum[left[p]]+num[right[p]]; else return find(right[p],mid+1,r,v);}int find2(int p,int l,int r,int v){ if (cnt[p]<2) return -1000000; if (cnt[p]==2) return num[p]+sum[p]; int mid=(l+r)/2; if (cnt[right[p]]>1&&num2[right[p]]<=v) return find2(right[p],mid+1,r,v); else if (cnt[left[p]]&&cnt[right[p]]&&sum[left[p]]+num[right[p]]<=v) return sum[left[p]]+num[right[p]]; else return find2(left[p],l,mid,v);}int main(){ num[0]=num2[0]=1000000; cnt[0]=0; scanf("%d",&ca); while (ca--){ scanf("%d",&n); fo(i,1,n) root[i]=0; fo(i,1,tot) left[i]=right[i]=0; tot=0; fo(i,1,n) build(root[i],1,n,i); fo(i,1,n) fa[i]=0; fo(i,1,n-1){ //printf("%d\n",i); scanf("%d%d",&j,&k); j=getfa(j); k=getfa(k); fa[k]=j; root[j]=merge(root[j],root[k],1,n); ans=(db)find(root[j],1,n,num[root[j]]+sum[root[j]])/2-num[root[j]]; now=sum[root[j]]-(db)find2(root[j],1,n,num[root[j]]+sum[root[j]])/2; if (now<ans) ans=now; printf("%.1lf\n",ans); } }}
- [HDU5604]守鹤之砂
- [hdu5604/bestcoder67E]merge
- 【GDOI2017模拟8.14】守鹤之砂
- 伊索寓言之(四)狼和鹤
- 復之之理
- 博学之,审问之,慎思之,明辨之,笃行之
- 博学之,审问之,慎思之,明辨之,笃行之
- 【保定七中】【①⑤②】 之爱心守侯
- 意守之法在《太平经》中已提出
- 禀父母·谨守父亲保身之则
- 算法题练习系列之(一):守形数
- 雪,之韵,之恋,之......
- 年终总结之天涯之无敌之言论
- 万源之源之drupal 之 drupal_flush_all_caches
- 编程之美------之数字之魅
- 之记录员
- 孔乙己之
- 浩杂收之
- Unity-Mobile Movie Texture视频插件的使用
- CornerStone的使用
- java 学习第四节 --void关键字
- 获取EditCtrl中数字的方法
- 滑轮控件的研究五、ViewConfiguration的简单介绍
- [HDU5604]守鹤之砂
- 欢迎使用CSDN-markdown编辑器
- android:电商app商品详情页浮动按钮效果
- C++系列——指针和数组详细分析
- RunLoop浅析
- 【MySQL学习笔记】CentOS 6.6上RPM包方式安装MySQL 5.6
- NSUserDefaults的一些基本用法
- 唯一实例
- 我的毕设涉及的东西