『STA - R1』Crossnews之单调栈

『STA - R1』Crossnews

题目背景

Informational problems make us better.

题目描述

定义两个序列 \{a_n\}\{b_n\} 的联合权值为

\operatorname{unval}(a,b)=\sum_{i=1}^nb_i(b_i-a_i)

现给定一个序列 \{a_n\},求满足 \operatorname{unval}(a,b) 最小的单调不减序列 \{b\},只需输出 \operatorname{unval}(a,b)的值即可。

注意,\{b\} 中的元素不一定要为整数。

输入格式

第一行一个正整数 n

第二行 n个整数表示a_i

输出格式

一行一个答案。

样例 #1

样例输入 #1

5

1 2 3 4 5

样例输出 #1

-13.7500000

样例 #2

样例输入 #2

10

1000 1 2 8 9 5 4 1000 -40 1000

样例输出 #2

-403015.7500000

样例 1 解释:使得联合权值取到最小值的 $\{b\}$ 为 0.5 1 1.5 2 2.5。


数据范围和约定:

对于全部数据,有 1\le n\le 10^6|a_i|\le 10^3


评分规则:

本题使用 Special Judge,如果你的答案是 pans,标准答案是 cans,则你将获得

\min\Bigg\{100,\Bigg\lfloor\dfrac{0.1}{\min\Big\{|pans-cans|,\Big|\dfrac{|pans-cans|}{cans}\Big|\Big\}}\Bigg\rfloor\Bigg\}

分。

每个 Subtask 内捆绑测试。即取 Subtask 内得分最小的作为 Subtask 得分。

题解

分析题目

若a为不减序列

在仅考虑一组数值 a , b 时存在函数  f(b)=b(b-a) ,其中 a 为定值。根据初中数学二次函数的相关概念可得 

 f(b)_{min}=f(\frac{a}{2})  

由此我们便可以推广到对于任意不减序列 a 都有唯一确定的不减序列 b 使得联合权值 unval(a,b) 最小,此时 b_i=\frac{a_i}{2}

在a的单调性不能保证时

将等式变形,得到

unval(a,b)=\sum_{i=1}^n (b_i-\dfrac{a_i}{2})^2-\sum_{i=1}^n \dfrac{a_i^2}{4}

假设一组数据 a_1a_2b_1b_2 满足 a_1>a_2b_1\le b_2 。  

不难发现此时的联合权值unval(a,b)(b_1-\dfrac{a_1}{2})^2+(b_2-\dfrac{a_2}{2})^2 成正相关,由平面间两点距离公式 |AB|=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2} 可得 (b_1-\dfrac{a_1}{2})^2+(b_2-\dfrac{a_2}{2})^2 是点 (b_1,b_2) 与点 (\frac{a_1}{2},\frac{a_2}{2}) 距离的平方。

因为a_1>a_2b_1\le b_2 ,所以点 (b_1,b_2) ,点(\frac{a_1}{2},\frac{a_2}{2}) 分居直线 y=x 两侧,因此当点 (b_1,b_2) 与点 (\frac{a_1}{2},\frac{a_2}{2}) 的连线与直线 $y=x$ 垂直,即 b_1=b_2=\frac{\frac{a_1}{2}+\frac{a_2}{2}}{2} 时两点距离最小,由此推广到整个序列 a , b 。此时联合权值 unval(a,b) 取到最小值。

实现方式

单调栈

由b序列单调不减的特性联想到单调栈,维护一个单调栈,在a序列单调不减时将 \frac{a_i}{2} 作为 b_i 入栈,否则不断弹栈至满足单调性,并计算其平均值再入栈。

压缩

不难发现,如果将每一个 b_i 作为单独的元素入栈会产生大量相邻的重复元素而造成资源浪费,因此可以使用结构体仅将元素数值和长度入栈。

下附代码

#include<bits/stdc++.h>
using namespace std;
struct Stu{
    int l;
    double x;
}st[1000010];
int n,top;
double ans,ls[1000010];
int a[1000010];
void print()//检查b值是否正确
{
    for(int i=0;i<=top-1;i++)
    {
        cout<<st[i].x<<" "<<st[i].l<<endl;
    }
}
int main()
{
    cin>>n;
    cout<<fixed<<setprecision(7);
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        ls[i]=1.0*a[i]/2;
        if(top==0)
            st[top].l=1,st[top++].x=ls[i];
        else{
            int l=1;
            double sum=ls[i];
            while(sum/l<st[top-1].x&&top!=0)
            {
                l+=st[top-1].l;
                sum+=st[top-1].x*st[top-1].l;
                top--;
            }
            st[top].x=sum/l,st[top++].l=l;
        }
    }
    //print();
    int z=1;
    for(int i=0;i<=top-1;i++)
    {
        for(int j=1;j<=st[i].l;j++)
        {
            ans+=st[i].x*(st[i].x-a[z++]);
        }
    }
    cout<<ans;
    return 0;
 } 

相关推荐

  1. Leetcoder Day43| 单调1

    2024-04-14 12:42:02       16 阅读
  2. STLstack 【

    2024-04-14 12:42:02       29 阅读
  3. C++ 单调 || 单调模版题

    2024-04-14 12:42:02       38 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-14 12:42:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-14 12:42:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-14 12:42:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-14 12:42:02       20 阅读

热门阅读

  1. 蓝桥杯算法题:小数第n位

    2024-04-14 12:42:02       17 阅读
  2. Qt第六章对话框

    2024-04-14 12:42:02       21 阅读
  3. SpringBoot 异步延时任务

    2024-04-14 12:42:02       38 阅读
  4. Asp.net 使用了 bootstrap,发布时样式丢失了

    2024-04-14 12:42:02       20 阅读
  5. Hadoop MapReduce解析

    2024-04-14 12:42:02       17 阅读
  6. ChatGPT指导下的学术写作:打造高质量论文

    2024-04-14 12:42:02       21 阅读
  7. Swift中的类

    2024-04-14 12:42:02       23 阅读