CF 1006C Three Parts of the Array【双指针/前缀和/后缀和/二分】
You are given an array d1,d2,…,dn consisting of n integer numbers.
Your task is to split this array into three parts (some of which may be empty) in such a way that each element of the array belongs to exactly one of the three parts, and each of the parts forms a consecutive contiguous subsegment (possibly, empty) of the original array.
Let the sum of elements of the first part be sum1, the sum of elements of the second part be sum2 and the sum of elements of the third part be sum3. Among all possible ways to split the array you have to choose a way such that sum1=sum3 and sum1 is maximum possible.
More formally, if the first part of the array contains a elements, the second part of the array contains b elements and the third part contains c elements, then:
sum1=∑1≤i≤adi,
sum2=∑a+1≤i≤a+bdi,
sum3=∑a+b+1≤i≤a+b+cdi.
The sum of an empty array is 0.
Your task is to find a way to split the array such that sum1=sum3 and sum1 is maximum possible.
Input
The first line of the input contains one integer n (1≤n≤2⋅105) — the number of elements in the array d.
The second line of the input contains n integers d1,d2,…,dn (1≤di≤109) — the elements of the array d.
Output
Print a single integer — the maximum possible value of sum1, considering that the condition sum1=sum3 must be met.
Obviously, at least one valid way to split the array exists (use a=c=0 and b=n).
Examples
Input
5
1 3 1 1 4
Output
5
Input
5
1 3 2 1 4
Output
4
Input
3
4 1 2
Output
0
Note
In the first example there is only one possible splitting which maximizes sum1: [1,3,1],[ ],[1,4].
In the second example the only way to have sum1=4 is: [1,3],[2,1],[4].
In the third example there is only one way to split the array: [ ],[4,1,2],[ ].
【题意】:将一个长度为n的数组划分为a,b,c三段(每一段都可以为空)使得a段和c段的和相等,问a段的和的最大值是多少?
【分析】:双指针求前缀和与后缀和进行大小比较,一遇到相等时打擂台求最大。注意要求和所以用LL,不然会WA10!
【代码】:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
#define ll long long
ll n,m;
ll a[N];
/*
将一个长度为n的数组划分为a,b,c三段(每一段都可以为空)
使得a段和c段的和相等,问a段的和的最大值是多少?
*/
int main()
{
while(~scanf("%lld",&n))
{
ll Max = 0, ls, rs;
for(ll i=0; i<n; i++)
{
scanf("%lld",&a[i]);
}
ll L = 0, R = n-1;
ls = a[L];
rs = a[R];
while(L < R)
{
if(ls == rs)
{
Max = max(Max,ls);
L++;
R--;
ls += a[L];
rs += a[R];
}
else if(ls > rs)
{
R--;
rs += a[R];
}
else
{
L++;
ls += a[L];
}
}
cout<<Max<<endl;
}
}
【二分】:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2*1e5+10;
ll n,a[maxn];
ll pre[maxn],suf[maxn];
/*
求前缀和,后缀和。然后从大到小枚举后缀,在前缀中查找相等,如果能找到且a,c两段不重叠,那么就是答案。注意开long long
*/
int main()
{
while(~scanf("%lld",&n))
{
ll Max = 0;
memset(pre,0,sizeof(pre));
memset(suf,0,sizeof(suf));
for(int i=0; i<n;i++)
{
scanf("%lld",&a[i]);
}
pre[0] = a[0];
for(int i=1;i<n;i++)
pre[i] = pre[i-1] + a[i];
suf[n-1] = a[n-1];
for(int i=n-2; i>=0; i--)
suf[i] = suf[i+1] + a[i];
for(int i=0; i<n; i++)
{
int pos = lower_bound(pre,pre+n,suf[i])-pre;
if(pos < i && pre[pos] == suf[i])
{
Max = max(Max,suf[i]);
}
}
printf("%lld\n",Max);
}
}
/*
n-1:4
0 1 2 3 4
1 2 3 4 5
5 9 12
*/
CF 1006C Three Parts of the Array【双指针/前缀和/后缀和/二分】的更多相关文章
- Codeforces 1006C:Three Parts of the Array(前缀和+map)
题目链接:http://codeforces.com/problemset/problem/1006/C (CSDN又改版了,复制粘贴来过来的题目没有排版了,好难看,以后就截图+题目链接了) 题目截图 ...
- CodeForces1006C-Three Parts of the Array
C. Three Parts of the Array time limit per test 1 second memory limit per test 256 megabytes input s ...
- <二分查找+双指针+前缀和>解决子数组和排序后的区间和
<二分查找+双指针+前缀和>解决子数组和排序后的区间和 题目重现: 给你一个数组 nums ,它包含 n 个正整数.你需要计算所有非空连续子数组的和,并将它们按升序排序,得到一个新的包含 ...
- [codeForce-1006C]-Three Parts of the Array (简单题)
You are given an array d1,d2,…,dnd1,d2,…,dn consisting of nn integer numbers. Your task is to split ...
- 【CF】220B Little Elephant and Array
区间动态统计的好题. /* */ #include <iostream> #include <string> #include <map> #include < ...
- CF1006C 【Three Parts of the Array】
二分查找水题 记$sum[i]$为$d[i]$的前缀和数组 枚举第一段区间的结尾$i$ 然后二分出$lower$_$bound(sum[n]-sum[i])$的位置$x$,如果$sum[x]$与$su ...
- [BZOJ3277/BZOJ3473] 串 - 后缀数组,二分,双指针,ST表,均摊分析
[BZOJ3277] 串 Description 现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Solution 首先将所有串连 ...
- LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
题意:有一个有序序列A,其内部可能有部分被旋转了,比如A[1...n]被转成A[mid...n]+A[1...mid-1],如果被旋转,只有这种形式.问最小元素是?(假设没有重复元素) 思路:如果是序 ...
- 【BZOJ3277/3473】串/字符串 后缀数组+二分+RMQ+双指针
[BZOJ3277]串 Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Inpu ...
随机推荐
- spring笔记(一)
1. 回顾 Struts与Hibernate可以做什么事? Struts, Mvc中控制层解决方案 可以进行请求数据自动封装.类型转换.文件上传.效验… Hibernate, 持久层的解决方案: 可以 ...
- 【bzoj4627】[BeiJing2016]回转寿司 离散化+树状数组
题目描述 给出一个长度为n的序列,求所有元素的和在[L,R]范围内的连续子序列的个数. 输入 第一行包含三个整数N,L和R,分别表示寿司盘数,满意度的下限和上限. 第二行包含N个整数Ai,表示小Z对寿 ...
- [洛谷P4779]【模板】单源最短路径(标准版)
题目大意:单元最短路径(卡$SPFA$) 题解:$dijkstra$($\underline{\hspace{0.5em}}\underline{\hspace{0.5em}}gnu\underlin ...
- 算法学习——st表
st表是一种基于倍增思想的DP. 用于求一个数列中的某个区间的最大/最小值. 用st[i][j]表示从第i个开始往后2^j个点,最大的是多少. 我们令k[i]表示2^i等于多少 那么有转移方程 st[ ...
- wmic的用法
原始文章链接:http://blog.sina.com.cn/s/blog_5fb265c70100w4d0.html 一.wmic的基本命令格式简析 经常看网上的相关资料的话,读者可能会对wmic有 ...
- 如何使用Photoshop批量扫描保存文档
以笔主手头上的Canon LIDE 100为例 先安装好扫描仪驱动程序,可使用自带驱动光盘或驱动精灵等程序完成. 打开Photoshop程序,以CS5为例,找到扫描仪入口: 点开高级模式进行配置,笔主 ...
- JavaScript的大括号的语义
Javascript中大括号"{}"有四种语义作用: 语义1. 组织复合语句,这是最常见的: view source print? 1 if( condition ) { 2 ...
- mycat 管理MySQL5.7主从搭建
1.首先安装MySQL ab: 192.168.6.163 master 192.168.6.167 slave master: vi /etc/opt/rh/rh-mysql57/my.cnf.d/ ...
- jquery从零起步学
html: <HTML> <head> <meta http-equiv="content-type" content="text/html ...
- babel-preset-es2015,babel-polyfill 与 babel-plugin-transform-runtime
babel-preset-es2015 是一个babel的插件,用于将部分ES6 语法转换为ES5 语法.转换的语法包括: 箭头函数 var a1 = () => 1 编译为 var a1 = ...