1. 程式人生 > 實用技巧 >[CF1299C] Water Balance - 單調棧

[CF1299C] Water Balance - 單調棧

Description

給定一個序列,可以進行無限次操作,每次選定一個區間,將該區間內的所有數變成區間的平均數,求操作後字典序最小的序列。

Solution

考慮單調棧,每次如果棧頂比帶入棧元素高就暴力彈棧,將被彈出的元素和帶入棧的元素合併。

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1000005;

int n;
int a[N];

struct Item 
{
    double val;
    int siz;
    bool operator < (const Item &x)
    {
        return val<x.val;
    }
    Item operator + (const Item &x)
    {
        Item res;
        res.siz=siz+x.siz;
        res.val=(val*siz+x.val*x.siz)/res.siz;
        return res;
    }
} sta[N];

int top;

signed main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        Item tmp={a[i],1};
        while(top && tmp<sta[top])
        {
            tmp=tmp+sta[top];
            --top;
        }
        sta[++top]=tmp;
    }
    for(int i=1;i<=top;i++)
    {
        for(int j=1;j<=sta[i].siz;j++)
        {
            printf("%.8lf\n",sta[i].val);
        }
    }
    return 0;
}