【二分答案】【中位数】codeforces 394 bun
bun
Description
因为体育老师很喜欢等差数列,所以他要求学生们站队必须按身高站成等差数列。
但是有些班级的学生无论如何也无法排成等差数列,于是体育老师从食堂买来了两种神
奇的面包。吃一个第一种面包可以使身高增 1,吃一个第二种面包可以使身高减 1。
你的任务是,对于某个班级,帮助老师安排哪些同学食用多少面包。考虑到学生的身体
健康,体育老师希望吃面包最多的学生吃的面包数量尽量少。
Input Format
第一行一个正整数 n,表示学生的数目。
第二行是长度为 n 的整数序列 a, a[i]表示第 i 个学生的身高。由于体育老师使用的奇怪
的身高单位,学生身高可能是负数。可以打乱顺序重新排列。
Output Format
第一行一个整数,表示吃面包最多的学生吃的面包数量。
第二行两个整数,分别表示等差数列的首项和公差,公差不能为负。
如果有多解,输出公差最小的方案。如果还有多解,输出首项最小的方案。
Sample Input (1)
5
-3 -4 -2 -3 3
Sample Output (1)
2
-3 1
Sample Input (2)
5
2 -3 -1 -4 3
第 8 页 共 8 页
Sample Output (2)
1
-4 2
Hint
对于 30%的数据,n<=100,a[i]的绝对值<=1000。
对于 60%的数据,n<=1000,a[i]的绝对值<=100000。
对于 100%的数据,n<=100000,a[i]的绝对值<=1000000。
<法一>记f1为当前需要吃的增高面包的最大的量,f2为当前需要吃的减低面包最大的量。
考虑暴力的情况,枚举公差d,我们可以通过计算f1、f2,再取中位数的方式得到当前的最优首项。
我们把每个d对应的f1、f2打出表来,就可以发现,f1单调递减,f2单调递增,它们两个相交的位置就是答案,二分即可(怕写错,写了分块答案)。
<法二>orz faebdc,我们在枚举d的时候,易发现,d最大不会超过4*max(a[i])/n,否则还不如把a全变0更优,因此暴力就好啦~
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 100001
int n,a[N],ans=2147483647,b[N],f1,f2,D,X0;
int main()
{
scanf("%d",&n);
if(n<=1000){
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int lim=30000000/n;
f1=f2=0;
for(int i=1;i<=n;++i)
{
b[i]=a[1]-a[i];
if(b[i]>0) f2=max(f2,b[i]);
else f1=max(f1,-b[i]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=0;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
for(int d=1;d<=lim;++d)
{
f1=f2=0;
for(int i=2;i<=n;++i)
{
b[i]+=(i-1);
if(b[i]>0) f2=max(f2,b[i]);
else f1=max(f1,-b[i]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=d;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
}
printf("%d\n%d %d\n",ans,X0,D);
return 0;
}
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
sort(a+1,a+n+1);
f1=f2=0;
for(int i=1;i<=n;++i)
{
b[i]=a[1]-a[i];
if(b[i]>0) f2=max(f2,b[i]);
else f1=max(f1,-b[i]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=0;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
if(f2>=f1)
{
printf("%d\n%d %d\n",ans,X0,D);
return 0;
}
int sz=sqrt(n),last=0;
for(int i=1;last<=n;i+=sz)
{
f1=f2=0;
for(int j=2;j<=n;++j)
{
b[j]+=(i==1?1:sz)*(j-1);
if(b[j]>0) f2=max(f2,b[j]);
else f1=max(f1,-b[j]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=i;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
if(f2>=f1)
{
for(int j=2;j<=n;++j)
b[j]-=(i==1?1:sz)*(j-1);
for(int j=last+1;j<=i;++j)
{
f1=f2=0;
for(int k=2;k<=n;++k)
{
b[k]+=(k-1);
if(b[k]>0) f2=max(f2,b[k]);
else f1=max(f1,-b[k]);
}
if(ans>((f1+f2+1)>>1))
{
ans=((f1+f2+1)>>1);
D=j;
if(f1<f2)
X0=a[1]-(((f1+f2+1)>>1)-f1);
else
X0=a[1]+(f1-((f1+f2+1)>>1));
}
if(f2>=f1)
{
printf("%d\n%d %d\n",ans,X0,D);
return 0;
}
}
}
last=i;
}
return 0;
}
【二分答案】【中位数】codeforces 394 bun的更多相关文章
- 【二分答案】Codeforces Round #402 (Div. 2) D. String Game
二分要删除几个,然后暴力判定. #include<cstdio> #include<cstring> using namespace std; int a[200010],n, ...
- Codeforces 700A As Fast As Possible(二分答案)
[题目链接] http://codeforces.com/problemset/problem/700/A [题目大意] 有一辆限载k人速度为v2的车,n个步行速度均为v1的人要通过一段长度为l的距离 ...
- Codeforces Round #276 (Div. 1) E. Sign on Fence (二分答案 主席树 区间合并)
链接:http://codeforces.com/contest/484/problem/E 题意: 给你n个数的,每个数代表高度: 再给出m个询问,每次询问[l,r]区间内连续w个数的最大的最小值: ...
- Codeforces Round #425 (Div. 2) Problem C Strange Radiation (Codeforces 832C) - 二分答案 - 数论
n people are standing on a coordinate axis in points with positive integer coordinates strictly less ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划
There are n people and k keys on a straight line. Every person wants to get to the office which is l ...
- Codeforces 772A Voltage Keepsake - 二分答案
You have n devices that you want to use simultaneously. The i-th device uses ai units of power per s ...
- Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) C. Save the Nature【枚举二分答案】
https://codeforces.com/contest/1241/problem/C You are an environmental activist at heart but the rea ...
- [Codeforces 1199C]MP3(离散化+二分答案)
[Codeforces 1199C]MP3(离散化+二分答案) 题面 给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r ...
- [Codeforces 865C]Gotta Go Fast(期望dp+二分答案)
[Codeforces 865C]Gotta Go Fast(期望dp+二分答案) 题面 一个游戏一共有n个关卡,对于第i关,用a[i]时间通过的概率为p[i],用b[i]通过的时间为1-p[i],每 ...
随机推荐
- 谈一谈深度学习之semantic Segmentation
上一次发博客已经是9月份的事了....这段时间公司的事实在是多,有写博客的时间都拿去看paper了..正好春节回来写点东西,也正好对这段时间做一个总结. 首先当然还是好好说点这段时间的主要工作:语义分 ...
- [bzoj 2733]启发式合并权值线段树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 平衡树待学习.从一个博客学到了合并权值线段树的姿势:http://blog.csdn ...
- Patch Windows with SSM on AWS
ec2ssmupdate https://docs.amazonaws.cn/systems-manager/latest/userguide/systems-manager-patch.htmlht ...
- AMD 和 CMD的区别
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出.CMD 是 SeaJS 在推广过程中对模块定义的规范化产出.类似的还有 CommonJS Modules/2.0 规范,是 Brav ...
- React 获取 url 参数 —— this.props.match
在 react 组件的 componentDidMount 方法中打印一下 this.props,在浏览器控制台中查看输出如下: 其中页面的 url 信息全都包含在 match 字段中,以地址 lo ...
- Linux下部署weblogic应用
1.Linux下weblogic安装 2.Linux下设置weblogic监听服务器地址(默认为本机) 1).修改domain\config\config.xml文件 修改 <server> ...
- CodeForces - 682B 题意水题
CodeForces - 682B Input The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — ...
- 动态规划&字符串:最长公共子串
还是直接上转移方程: 动规只能解决O(n^2)的最长公共子串问题 使用后缀数组或者SAM可以高效地解决这个问题 所以,对于这个问题,动规的代码就不给出了 直接给出SAM的实现,也为以后学习SAM打下一 ...
- bzoj 1050: [HAOI2006]旅行comf&&【codevs1001】
Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求 一条路径,使得路径上最 ...
- linux shell 脚本实现tcp/upd协议通讯(重定向应用)
linux shell 脚本实现tcp/upd协议通讯(重定向应用) http://www.cnblogs.com/chengmo/archive/2010/10/22/1858302.html