【2020.11.17提高组模拟】数数(cuvelia) 题解

题目描述

给你一个长度为n的序列\(a_1...a_n\)。对于所有的\(k\in [1,n]\)选择序列中的\(k\)个数(下标为\(i_1,i_2...i_k\)),使得\(\sum_{l=1}^k\sum_{r=l}^k|a_{i_l}-a_{i_r}|\)最大,并对于每个\(k\)求出这个最大值。

\(n\le 3\times 10^5\)。

\(|a_i|\le 10^6\)

题意分析

求从一个序列中有序地取出k个数后的最大值,该值为每个数减去其前面所有数的绝对值之和。

首先对原序列排序。排序不影响答案。

接着,显然取出最大和最小值一定没错的。

再依次从没有取出的数中,取最小的和最大的放在取出的序列中间。

这个又为什么是对的呢?

考虑现在要取出的数放到取出的序列中间时,左右各有\(lsize\),\(rsize\)个数,左右数字和各为\(lsum\),\(rsum\)。

那么插入这个数\(x\)对答案的贡献为

\[(rsum-rsize*x)+(lsize*sum-lsum)
\]

提取

\[(rsum-lsum)-(rsize-lsize)*x
\]

这个式子同时解释了为什么整个取出序列必须时升序的,且要从最大值和最小值开始取数,以及为什么要尽量保持左右数的数量平均。

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#define debug printf("Now is %d\n",__LINE__);
using namespace std; template<class T>inline void read(T&x)
{
char ch=getchar();
int fu;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
x*=fu;
}
inline int read()
{
int x=0,fu=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*fu;
}
int G[55];
template<class T>inline void write(T x)
{
int g=0;
if(x<0) x=-x,putchar('-');
do{G[++g]=x%10;x/=10;}while(x);
for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
}
LL a[1000010];
LL ansxb[1000][1000];
LL ans[1000];
int n;
int main()
{
freopen("cuvelia.in","r",stdin);
freopen("cuvelia.out","w",stdout);
n=read();
for(int i=1;i<=n;i++) a[i]=read();
sort(a+1,a+n+1);
if(n<=5)
{
do
{
re LL now=0;
for(re int i=1;i<=n;i++)
{
for(re int j=1;j<=i;j++) now+=abs(a[i]-a[j]);
if(now>ans[i])
{
ans[i]=now;
for(int j=1;j<=i;j++) ansxb[i][j]=a[j];
}
}
}while(next_permutation(a+1,a+n+1));
for(re int i=1;i<=n;i++)
{
cout<<ans[i]<<endl;
// cout<<i<<":"<<ans[i]<<" = ";
// for(re int j=1;j<=i;j++)
// {
// cout<<ansxb[i][j]<<" ";
// }
// cout<<endl;
}
}
else
{
cout<<0<<endl;
LL ans=a[n]-a[1];
LL l=2,r=n-1,lsum=a[1],lsize=1,rsum=a[n],rsize=1;
cout<<ans<<endl;
for(re int i=3;i<=n;i++)
{
if(i&1)
{
ans+=rsum-rsize*a[l]-lsum+lsize*a[l];
lsum+=a[l];
lsize++;
l++;
}
else
{
ans+=rsum-rsize*a[r]-lsum+lsize*a[r];
rsum+=a[r];
rsize++;
r--;
}
write(ans);
}
}
return 0;
}

结语

考试的时候不知道为什么脑子抽到了,用了\(cout\)来输出这\(3*10^5\)个答案。

然后就

\[100\Rightarrow70\\
Rank19\Rightarrow36
\]

好耶!(

【2020.11.17提高组模拟】数数(cuvelia) 题解的更多相关文章

  1. 【2020.11.28提高组模拟】T1染色(color)

    [2020.11.28提高组模拟]T1染色(color) 题目 题目描述 给定 \(n\),你现在需要给整数 \(1\) 到 \(n\) 进行染色,使得对于所有的 \(1\leq i<j\leq ...

  2. 【2020.11.28提高组模拟】T2 序列(array)

    序列(array) 题目描述 ​给定一个长为 \(m\) 的序列 \(a\). 有一个长为 \(m\) 的序列 \(b\),需满足 \(0\leq b_i \leq n\),\(\sum_{i=1}^ ...

  3. 【2020.11.30提高组模拟】剪辣椒(chilli)

    剪辣椒(chilli) 题目描述 在花园里劳累了一上午之后,你决定用自己种的干辣椒奖励自己. 你有n个辣椒,这些辣椒用n-1条绳子连接在一起,任意两个辣椒通过用若干个绳子相连,即形成一棵树. 你决定分 ...

  4. 【2020.11.30提高组模拟】删边(delete)

    删边(delete) 题目 题目描述 给你一棵n个结点的树,每个结点有一个权值,删除一条边的费用为该边连接的两个子树中结点权值最大值之和.现要删除树中的所有边,删除边的顺序可以任意设定,请计算出所有方 ...

  5. JZOJ 【2020.11.30提高组模拟】剪辣椒(chilli)

    题目大意 给出一棵 \(n\) 个节点的树,删去其中两条边 使得分出的三个子树大小中最大与最小的差最小 分析 先一边 \(dfs\) 预处理出以 \(1\) 为根每个点的 \(size\) 然后按 \ ...

  6. JZOJ 6904. 【2020.11.28提高组模拟】T3 树上询问(query)

    题目 你有一棵 \(n\) 节点的树 ,回答 \(m\) 个询问,每次询问给你两个整数 \(l,r\) ,问存在多少个整数 \(k\) 使得从 \(l\) 沿着 \(l \to r\) 的简单路径走 ...

  7. 【2020.12.01提高组模拟】卡特兰数(catalan)

    题目 题目描述 今天,接触信息学不久的小\(A\)刚刚学习了卡特兰数. 卡特兰数的一个经典定义是,将\(n\)个数依次入栈,合法的出栈序列个数. 小\(A\)觉得这样的情况太平凡了.于是,他给出了\( ...

  8. 11.5NOIP2018提高组模拟题

    书信(letter) Description 有 n 个小朋友, 编号为 1 到 n, 他们每人写了一封信, 放到了一个信箱里, 接下来每个人从中抽取一封书信. 显然, 这样一共有 n!种拿到书信的情 ...

  9. 【2020.12.01提高组模拟】A组反思

    105,rk45 T1 赛时一开始先打了\(m=0\)的情况,也就是普通的卡特兰数,然后打了暴力,样例过了,把样例改改就不行了,原因没有保证是枚举的是合法的出栈序列 得分:\(WA\&TLE1 ...

  10. 【2020.12.02提高组模拟】球员(player)

    题目 题目描述 老师们已经知道学生喜欢睡觉,Soaring是这项记录保持者.他只会在吃饭或玩FIFA20时才会醒来.因此,他经常做关于足球的梦,在他最近的一次梦中,他发现自己成了皇家马德里足球俱乐部的 ...

随机推荐

  1. idea社区版配置springboot项目问题分析及处理

    前言 记录一次使用IDEA社区版配置SpringBoot项目的经历,包括遇到的问题及解决过程 IDEA版本:IntelliJ IDEA 2024.2.3 (Community Edition) 问题描 ...

  2. winform 实现太阳,地球,月球 运作规律https://www.cnblogs.com/axing/p/18762710

    无图眼吊(动图)    缘由 最近我太太在考公学习,给我出了两道高中地理知识的题目,把我问的一头雾水,题目是这样的 第一题 第二题 看到这两道题,当时大脑飞速运转,差点整个身体都在自转了,所以产生了个 ...

  3. Qt 实现带阴影 无边框的QMessageBox

    Qt 实现带阴影的QMessagebox 在实际项目里面使用到了QMessageBox做一个弹窗,最开始是样式不是需要的样式,就去找了一下QMessageBox的样式表,一般来说可以使用findChi ...

  4. manim边学边做--移动相机的场景类

    Manim作为强大的数学动画引擎,其核心功能之一是实现复杂的镜头运动控制. MovingCameraScene类正是为满足这种需求而设计的专业场景类. 与基础Scene类相比,它通过以下特性拓展了镜头 ...

  5. 解决vscode"无法加载文件 ,因为在此系统上禁止运行脚本"报错

    问题 在使用 vscode 自带程序终端时,会报"无法加载文件 ,因为在此系统上禁止运行脚本",这是因为 PowerShell 执行策略的问题. > tsc --init t ...

  6. Linux重启php-fpm

    前言 PHP-FPM 是一款简单好用的 PHP FastCGI 进程管理工具. 它可以和 Apache.Nginx 或其他服务器一起构建完整的 PHP 环境. 接下来我们看看在更改了 php.ini ...

  7. Oracle配置和性能优化方法

          性能是衡量软件系统的一个重要部分,可能引起性能低下的原因很多,如CPU/内存/网络资源不足,硬盘读写速度慢,数据库配置不合理,数据库对象规划或存储方式不合理,模块设计对性能考虑不足等. 1 ...

  8. IDA Pro分析dll在exe中的表现

    尝试分析隐式加载和显式加载的dll在exe中进行反汇编时的表现. 1. 测试条件 (1)动态库 testdll1  导出函数 int add(int, int) 和  int add2(int, in ...

  9. 多态的前提--java进阶day02

    1.多态的前提条件 第一点和第二点都很好理解,第三点父类引用指向子类对象是什么意思?以下图进行讲解 我们以前的写法,如下图,叫做子类引用指向子类 那父类引用呢?就是把左边换成父类Animal即可 因为 ...

  10. 【Maven】仓库

    在 Maven 的术语中,仓库是一个位置(place). Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库. 在 Maven 中,任何一个依赖.插件或者项目构建的输出,都可以称之为构件 ...