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. 分析: 一眼看 ...
随机推荐
- RocketMQ实战快速入门
转自:https://www.jianshu.com/p/824066d70da8 一.RocketMQ 是什么 Github 上关于 RocketMQ 的介绍:RcoketMQ 是一款低延 ...
- nodejs,javascript过滤emoj表情
1 前言 由于带emoj表情的昵称无法存储在mysql character_set_server= utf8模式下,按照参考文章[1],改成utf8mb4,无效(可能使用方法不对). 总体思路是,把昵 ...
- 【进阶3-1期】JavaScript深入之史上最全--5种this绑定全面解析(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://github.com/yygmind/blog/issues/20 this的绑定规则总共有下面5种. 1.默认绑定(严格/非严 ...
- oracle提高查询效率的34条方法
注:本文来源:远方的守望者 <oracle提高查询效率的34条方法> oracle提高查询效率的34条方法 1.选择最有效率的表名顺序 (只在基于规则的优化器中有效): ORACLE的解 ...
- Confluence 6 配置管理员联系页面
管理员联系页面是一个格式化的页面,这个页面能够允许 Confluence 用户在 Confluence 中向管理员发送消息(在这部分的内容,管理员是默认管理员用户组的成员). 有关用户组的解释,请参考 ...
- 放一点百度来的,常见的windowserror
0操作成功完成.1功能错误.2系统找不到指定的文件.3系统找不到指定的路径.4系统无法打开文件.5拒绝访问.6句柄无效.7存储控制块被损坏.8存储空间不足,无法处理此命令.9存储控制块地址无效.10环 ...
- Java并发编程-并发工具类及线程池
JUC中提供了几个比较常用的并发工具类,比如CountDownLatch.CyclicBarrier.Semaphore. CountDownLatch: countdownlatch是一个同步工具类 ...
- LeetCode(82):删除排序链表中的重复元素 II
Medium! 题目描述: 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 1: 输入: 1->2->3->3->4->4- ...
- uva11916 bsgs算法逆元模板,求逆元,组合计数
其实思维难度不是很大,但是各种处理很麻烦,公式推导到最后就是一个bsgs算法解方程 /* 要给M行N列的网格染色,其中有B个不用染色,其他每个格子涂一种颜色,同一列上下两个格子不能染相同的颜色 涂色方 ...
- cf581F 依赖背包+临时数组 好题
这题得加个临时数组才能做.. /* 给定一棵树,树节点可以染黑白,要求叶子节点黑白平分 称连接黑白点的边为杂边,求使得杂边最少的染色方 那么设dp[i][j][0|1]表示i子树中有j个叶子节点,i染 ...