题目链接
题目大意:给你一个长度为n的数组,你可以选择一段区间将这段区间的数全都变成这段区间的平均值,问你最后这个数组字典序最小是怎么样的
解题思路:1.首先我们知道最后这个序列一定会变成一个单调上升的子序列
2.然后我们发现操作之后序列会变成一块一块的,每一块的数字都是相同的,那么我们可以按照分块的思想,如果这一块平均值比前面的小就合并到前面去
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define for_(i,a,b) for( int i = (a); i >= (b); -- i)
#define rep_(i,a,b) for( int i = (a); i > (b); -- i)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define hash Hash
#define next Next
#define count Count
#define pb push_back
#define Setw(a) fixed<
#define f first
#define s second
using namespace std;
const int N = 1e6+10, mod = 1e9 + 7;
const double eps = 1e-10;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args)
{
read(first);
read(args...);
}
double a[N], ans[N];
int block[N], l;
int main()
{
int T;
read(T);
_for(i,1,T+1) read(a[i]);
_for(i,1,T+1)
{
ans[++ l] = a[i];
block[l] = 1;
while(l > 1 && ans[l] < ans[l - 1])
{
ans[l - 1] = (ans[l] * block[l] + ans[l - 1] * block[l - 1]) / (block[l] + block[l - 1]);
block[l - 1] = block[l - 1] + block[l];
l --;
}
}
_for(i,1,l+1)
_for(j,1,block[i]+1)
cout <<Setw(10) << ans[i] << "\n";
return 0;
}