AtCoder Regular Contest 100 (ARC100) D - Equal Cut 二分
原文链接https://www.cnblogs.com/zhouzhendong/p/9251420.html
题目传送门 - ARC100D
题意
给你一个长度为 $n$ 的数列,请切 $3$ 刀,形成 $4$ 个连续非空子序列,问这 $4$ 个非空子序列的各自的元素和 的极差为多少。
$n\leq 2\times 10 ^5$
题解
如果切一刀,那么问题就很简单,尽量选中间的就可以了。
可以二分一下在 $O(\log n)$ 的复杂度内解决。
于是本题可以先枚举一下中间那条线,然后对于两边转化成刚才的子问题。
然而!
关键是:我居然没有想到,大概是脑抽了吧。
然而!
我通过乱搞过掉了!!
本题第一次让我感受到了乱搞的强大!!
UPD:突然发现正解可以通过指针扫一遍实现 $O(n)$ 。
代码
正解我没写过。这里放乱搞,仅供观看,别喷谢谢。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200005;
int n;
LL a[N],sum[N],v;
int x[5]={0};
LL calc(int i){
return sum[x[i]]-sum[x[i-1]];
}
LL llabs(LL x){
return x<0?-x:x;
}
bool cmp(int a,int b){
return calc(a)<calc(b);
}
bool cmp2(int a,int b){
return calc(a)>calc(b);
}
void move(int id,int d){
if (d==1){
if (x[id+1]-x[id]>1)
x[id]++;
}
else {
if (x[id]-x[id-1]>1)
x[id]--;
}
}
LL trys(){
LL ans=1e17;
int y[5];
for (int i=0;i<5;i++)
y[i]=x[i];
for (int i=1;i<=20;i++){
int id[5]={0,1,2,3,4};
sort(id+1,id+5,cmp);
ans=min(ans,llabs(calc(id[1])-calc(id[4])));
int r=rand()%6;
if (r==0){
LL val=calc(1);
if (val>v)
move(1,-1);
else
move(1,1);
}
if (r==1){
LL val=calc(4);
if (val>v)
move(3,1);
else
move(3,-1);
}
if (r>1){
r-=2;
int k=r&1?2:3;
r/=2;
LL val=calc(k);
if (r){
if (val>v)
move(k-1,1);
else
move(k-1,-1);
}
else {
if (val>v)
move(k,-1);
else
move(k,1);
}
}
}
for (int i=0;i<5;i++)
x[i]=y[i];
return ans;
}
LL solve(){
for (int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
v=sum[n]/4;
for (int i=1;i<=3;i++){
x[i]=x[i-1]+1;
while (x[i]<n+i-4&&sum[x[i]]-sum[x[i-1]]<=v)
x[i]++;
}
x[4]=n;
LL ans=1e17;
for (int xxxx=1;xxxx<=n*4;xxxx++){
ans=min(ans,trys());
int id[5]={0,1,2,3,4};
sort(id+1,id+5,cmp);
ans=min(ans,llabs(calc(id[1])-calc(id[4])));
int j=1;
while (j<=4&&(id[j]==1||x[id[j]-1]-x[id[j]-2]==1))
j++;
if (j>4)
break;
x[id[j]-1]--;
}
return ans;
}
LL solve2(){
for (int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i];
v=sum[n]/4;
for (int i=1;i<=3;i++){
x[i]=x[i-1]+1;
while (x[i]<n+i-4&&sum[x[i+1]]-sum[x[i]]<=v)
x[i]++;
}
x[4]=n;
LL ans=1e17;
for (int xxxx=1;xxxx<=n*4;xxxx++){
int id[5]={0,1,2,3,4};
sort(id+1,id+5,cmp2);
ans=min(ans,llabs(calc(id[1])-calc(id[4])));
int j=1;
while (j<=4&&(id[j]==1||x[id[j]-1]-x[id[j]-2]==1))
j++;
if (j>4)
break;
x[id[j]-1]--;
}
return ans;
}
int main(){
srand(19260817);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lld",&a[i]);
LL ans=1e17;
ans=min(ans,solve());
for (int i=1;i<=n/2;i++)
swap(a[i],a[n-i+1]);
ans=min(ans,solve());
ans=min(ans,solve2());
for (int i=1;i<=n/2;i++)
swap(a[i],a[n-i+1]);
ans=min(ans,solve2());
printf("%lld",ans);
return 0;
}
AtCoder Regular Contest 100 (ARC100) D - Equal Cut 二分的更多相关文章
- AtCoder Regular Contest 100 (ARC100) E - Or Plus Max 其他
原文链接https://www.cnblogs.com/zhouzhendong/p/9251448.html 题目传送门 - ARC100E 题意 给定一个正整数 $n(n\leq 18)$. 然后 ...
- AtCoder Regular Contest 100 Equal Cut
Equal Cut 思路: 枚举中间那个分界点,然后两边找使得切割后差值最小的点,这个可以用双指针 代码: #include<bits/stdc++.h> using namespace ...
- AtCoder Regular Contest 100
传送门 C - Linear Approximation 题意: 求 \[ \sum_{i=1}^nabs(A_i-(b+i)) \] \(A_i,b\)给出. 思路: 将括号拆开,变为\(A_i-i ...
- AtCoder Regular Contest 100 E - Or Plus Max
一道很好的dp题 dp[K]存的是 i满足二进制1属于K二进制1位置 最大的两个Ai 这样dp[K]统计的两个数肯定满足(i | j) <= K 然后不断做 update(dp[i | (1&l ...
- AtCoder Regular Contest 084 C - Snuke Festival【二分】
C - Snuke Festival ....最后想到了,可是不应该枚举a[],这样要二重循环,而应该枚举b[],这样只需一重循环... #include<iostream> #inclu ...
- AtCoder Beginner Contest 100 2018/06/16
A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
- AtCoder Regular Contest 097
AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...
随机推荐
- HBase基础架构及原理
1. HBase框架简单介绍 HBase是一个分布式的.面向列的开源数据库,它不同于一般的关系数据库,是一个适合于非结构化数据存储的数据库.另一个不同的是HBase基于列的而不是基于行的模式.HBas ...
- 前端 --- 关于DOM的介绍
111 什么是DOM DOM:文档对象模型.DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构.目的其实就是为了能让js操作html元素而制定的一个规范. DOM就是由节点组成的. 解 ...
- Ex 2_4 假定您需要在以下三种算法中作出抉择..._第三次作业
- LVM初级配置
步骤: 1.将物理硬盘转换成物理卷(PV) 创建PV:pvcreate /dev/vdb 2.将PV添加到卷组中(VG) vgcreate vg0 /dev/vdb 3.创建逻辑卷(LV)并从VG中调 ...
- js——this
每个函数的this是在调用时绑定的,完全取决于函数的调用位置 1. 绑定规则总结 一般情况下,按下列顺序从下至上来判断this的绑定对象(绑定的优先级从下至上递减) 默认:在严格模式下绑定到undef ...
- InstallUtil操作WindowsService
要安装windows service 首先要找到 InstallUtil.exe,InstallUtil.exe位置在 C:\Windows\Microsoft.NET\Framework\v4.0. ...
- 关于npm 淘宝镜像 以及package.json里包的更新
1.淘宝镜像的设置 npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm ...
- Zookeeper的Watcher 机制的实现原理
基于 Java API 初探 zookeeper 的使用: 先来简单看一下API的使用: public class ConnectionDemo { public static void main(S ...
- python(8):面向对象编程
有三种程序类型: (1)面向过程:按照一定的逻辑顺序,一步步垒代码 (2)面向函数:对用常用的计算,建立函数避免重复 (3)面向对象: 函数的集合,对函数进行分类和封装 (一) 抽象 抽象: 哈巴狗, ...
- 20165314 2016-2017-2 《Java程序设计》第9周学习总结
20165314 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 URl类 UDP数据报 广播数据报 套接字 套接字连接机制 代码托管