【2020.11.17提高组模拟】数数(cuvelia) 题解
【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\)对答案的贡献为
\]
提取
\]
这个式子同时解释了为什么整个取出序列必须时升序的,且要从最大值和最小值开始取数,以及为什么要尽量保持左右数的数量平均。
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\)个答案。
然后就
Rank19\Rightarrow36
\]
好耶!(
【2020.11.17提高组模拟】数数(cuvelia) 题解的更多相关文章
- 【2020.11.28提高组模拟】T1染色(color)
[2020.11.28提高组模拟]T1染色(color) 题目 题目描述 给定 \(n\),你现在需要给整数 \(1\) 到 \(n\) 进行染色,使得对于所有的 \(1\leq i<j\leq ...
- 【2020.11.28提高组模拟】T2 序列(array)
序列(array) 题目描述 给定一个长为 \(m\) 的序列 \(a\). 有一个长为 \(m\) 的序列 \(b\),需满足 \(0\leq b_i \leq n\),\(\sum_{i=1}^ ...
- 【2020.11.30提高组模拟】剪辣椒(chilli)
剪辣椒(chilli) 题目描述 在花园里劳累了一上午之后,你决定用自己种的干辣椒奖励自己. 你有n个辣椒,这些辣椒用n-1条绳子连接在一起,任意两个辣椒通过用若干个绳子相连,即形成一棵树. 你决定分 ...
- 【2020.11.30提高组模拟】删边(delete)
删边(delete) 题目 题目描述 给你一棵n个结点的树,每个结点有一个权值,删除一条边的费用为该边连接的两个子树中结点权值最大值之和.现要删除树中的所有边,删除边的顺序可以任意设定,请计算出所有方 ...
- JZOJ 【2020.11.30提高组模拟】剪辣椒(chilli)
题目大意 给出一棵 \(n\) 个节点的树,删去其中两条边 使得分出的三个子树大小中最大与最小的差最小 分析 先一边 \(dfs\) 预处理出以 \(1\) 为根每个点的 \(size\) 然后按 \ ...
- JZOJ 6904. 【2020.11.28提高组模拟】T3 树上询问(query)
题目 你有一棵 \(n\) 节点的树 ,回答 \(m\) 个询问,每次询问给你两个整数 \(l,r\) ,问存在多少个整数 \(k\) 使得从 \(l\) 沿着 \(l \to r\) 的简单路径走 ...
- 【2020.12.01提高组模拟】卡特兰数(catalan)
题目 题目描述 今天,接触信息学不久的小\(A\)刚刚学习了卡特兰数. 卡特兰数的一个经典定义是,将\(n\)个数依次入栈,合法的出栈序列个数. 小\(A\)觉得这样的情况太平凡了.于是,他给出了\( ...
- 11.5NOIP2018提高组模拟题
书信(letter) Description 有 n 个小朋友, 编号为 1 到 n, 他们每人写了一封信, 放到了一个信箱里, 接下来每个人从中抽取一封书信. 显然, 这样一共有 n!种拿到书信的情 ...
- 【2020.12.01提高组模拟】A组反思
105,rk45 T1 赛时一开始先打了\(m=0\)的情况,也就是普通的卡特兰数,然后打了暴力,样例过了,把样例改改就不行了,原因没有保证是枚举的是合法的出栈序列 得分:\(WA\&TLE1 ...
- 【2020.12.02提高组模拟】球员(player)
题目 题目描述 老师们已经知道学生喜欢睡觉,Soaring是这项记录保持者.他只会在吃饭或玩FIFA20时才会醒来.因此,他经常做关于足球的梦,在他最近的一次梦中,他发现自己成了皇家马德里足球俱乐部的 ...
随机推荐
- 分享一个 Win11 隐藏右下角日期时间的解决方案
分享一个 Win11 隐藏右下角日期时间的解决方案
- linux的zip命令详解 | Linux文件打包成Zip的命令和方法
zip 命令用来压缩文件 参数: -A:调整可执行的自动解压缩文件: -b<工作目录>:指定暂时存放文件的目录: -c:替每个被压缩的文件加上注释: -d:从压缩文件内删除指定的文件: - ...
- 运维 —— IMP-00030: failed to create file import_sys for write
IMP-00030: failed to create file import_sys for writeIMP-00000: Import terminated unsuccessfully原因:操 ...
- oracle 数据库服务名怎么查
WINDOWS上,直接看 服务里的 服务名就好:Oracle SID Service ,中间的SID就是数据库服务的名称.LINUX系统下,输入env |grep SID 可以查看到,一般没换都是这个 ...
- llamacpp转换hf、vllm运行gguf
Linux通过huggingface安装大模型 huggingface官网 https://huggingface.co/ wget https://repo.anaconda.com/minicon ...
- AspNetCore MVC 跨域
通过XMLHttpRequest或者ajax去请求一个AspNetCore API接口服务时,Firefox提示我 已拦截跨源请求:同源策略禁止读取位于 http://localhost:33694/ ...
- Golang服务可观测和思路分享
省流 中医四诊"望闻问切"与程序诊断有异曲同工之妙.在Golang问题排查中,我们需要建立系统化的诊断思维:通过观察表象(望).收集信息(闻).追溯根源(问).精准施治(切)四个维 ...
- MySQL 中 `LIMIT 100000000, 10` 和 `LIMIT 10` 的执行速度是否相同?
在MySQL中,LIMIT 100000000, 10和LIMIT 10的执行速度通常不会相同.它们的差异在于如何处理数据的检索. LIMIT 10: LIMIT 10表示从查询结果中获取前10条记录 ...
- uniapp阻止Modal模态框关闭
要阻止uniapp的Modal模态框关闭,没有找到相关api,但可以通过保存配置立即打开的方式变相实现阻止关闭: const option = { title: "输入礼品券名称" ...
- 前端速成之路——html、css
项目一知识点 单表视图列表 标题标签 <h1>用户注册</h1> 分割线与换行 <hr> <br> 表单提交 get:通过浏览器地址栏传递值 post: ...