【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. 一次h5活动页面的踩坑 过程

    托好奇心的福,这几天又接了一个bug,哦不,一个非常锻炼个人能力的h5页面,期间涉及到很多问题,在此打算先占个坑,等日后有时间再慢慢记录,无论是swiper插件的使用,还是关于硬件加速的运用,又或者是 ...

  2. Apache Tomcat RCE漏洞复现(CVE-2025-24813)

    漏洞描述 该漏洞的核心在于不完整PUT请求上传时 Tomcat 会使用了一个基于用户提供的文件名和路径生成的临时文件,且路径分隔符被替换为 . . 若同时满足以下条件,攻击者可执行任意代码: 默认 S ...

  3. Manus,没有秘密「注解版」

    近来Manus走红,「争论」不断,我也在前文<Manus爆火,是硬核还是营销?>中阐述过自Manus发布后,行业讨论以及开源复刻的信息,以及我们如何结合蚂蚁图计算(TuGraph)技术,实 ...

  4. 第一次记录自己的java学习日常,之前都是看其他博主的java知识,现在该自己记录一下了。

    对知识做总结 在学校呢,走过了非常多的坑,参加了一些比赛,但是也没有学到什么(含金量高的比赛可以参加,但是需参加之前先沉淀好自己的技术,不要报名了才去准备,得在准备中去报名),学校教的知识都是理论化, ...

  5. 【JVM之内存与垃圾回收篇】垃圾回收相关概念

    垃圾回收相关概念 System.gc() 的理解 在默认情况下,通过 System.gc() 或者 Runtime.getRuntime().gc() 的调用,会显式触发 FullGC,同时对新生代. ...

  6. 神级辅助工具,解决GPT-SoVITS配音发音纠正和逐句优化

    即使地表最强AI配音也无法自动识别360应配音成三百六十还是三六零,在长文配音中很难一次满意,总会因为个别几句配音不理想而毁掉整个配音成果. 在GPT-SoVITS配音中,自动把长文章拆分成段落或长句 ...

  7. AQS的acquire(int arg) 方法底层源码

    一.定义 acquire(int arg) 是 AQS(AbstractQueuedSynchronizer)中的一个核心方法,用于在独占模式下获取同步状态.如果当前线程无法获取同步状态,则将其加入等 ...

  8. MySQL 的索引类型有哪些?

    MySQL 的索引类型 MySQL 提供多种索引类型,用于优化数据查询性能.每种索引类型在存储结构.适用场景和性能特性方面各不相同. 1. 常见的索引类型 (1)B+树索引 结构:基于 B+ 树实现, ...

  9. app自动化设计

    一.在pom.xml引入依赖 testng:测试框架用例管理 appium:需要用到appium log4j:日志集成 allure:生成报告 二.po分层 分为基础层,page层,用例层,xml文件 ...

  10. app自动化的特殊操作

    一.截屏 File srcfile=driver.getScreenshotAs(OutputType.FILE); //得到截图源文件对象 File dstfile=new File("C ...