https://vjudge.net/problem/CodeForces-1300E
题目大意:给一个数组,每次操作可以选取一个区间
[
l
,
r
]
[l,r]
[l,r],使得
a
[
l
…
r
]
=
∑
i
=
l
r
a
[
i
]
/
(
r
−
l
+
1
)
a[l…r]=\sum_{i=l}^{r}a[i]/(r-l+1)
a[l…r]=∑i=lra[i]/(r−l+1)。问这个数组的最小的字典序。
思路:贪心的想一下,肯定要让左侧的数尽可能的小,那么如果 a n s [ i ] > = a n s [ i − 1 ] ans[i]>=ans[i-1] ans[i]>=ans[i−1],我们就可以把这些数合并起来,那么搞一个单调栈维护就行了,同时搞一个 b l o c k block block数组记录当前块的元素个数。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int block[maxn];
double ans[maxn];
int main()
{
int n,v,len=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&v);
ans[++len]=v;
block[len]=1;
while(ans[len]<=ans[len-1])
{
if(ans[len]<ans[len-1])
ans[len-1]=(ans[len-1]*block[len-1]+ans[len]*block[len])/(block[len-1]+block[len]);
block[len-1]+=block[len];
--len;
}
}
for(int i=1;i<=len;i++)
for(int j=0;j<block[i];j++)
printf("%.10f\n",ans[i]);
return 0;
}