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 ...
随机推荐
- 【bzoj4548】小奇的糖果 STL-set+树状数组
题目描述 平面上有n个点,每个点有一种颜色.对于某一条线段,选择所有其上方或下方的点.求:在不包含所有颜色的点的前提下,选择的点数最多是多少.(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算 ...
- 【题解】NOIP2016愤怒的小鸟
一眼n<=18状压dp……方程什么的都很显然,枚举两只小鸟,再将这条抛物线上的小鸟抓出来就好啦.只是这样O(n^3)的dp必然是要TLE的,我一开始这样交上去显然跑得巨慢无比,后来转念一想:面对 ...
- 洛谷 P2801 教主的魔法 解题报告
P2801 教主的魔法 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.--.N. ...
- Ubuntu使用vim编辑器时出现上下左右键变成ABCD
今天在配置安装php时,要打开配置文件做些修改,肯定是要使用到vim编辑器的,我按照之前的使用命令之类的,在用到上下左右键时居然出现了ABCD,这我就纳闷了,难道Ubuntu的vim编辑器和别的不一样 ...
- 兔子与兔子 [Hash]
兔子与兔子 描述 很久很久以前,森林里住着一群兔子.有一天,兔子们想要研究自己的 DNA 序列.我们首先选取一个好长好长的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 个小写英文字母) ...
- sperman系数
https://baike.baidu.com/item/spearman%E7%9B%B8%E5%85%B3%E7%B3%BB%E6%95%B0/7977847?fr=aladdin https:/ ...
- 为什么 Java中1000==1000为false而100==100为true?AND "2+2=5"?
前提:我们知道,如果两个引用指向同一个对象,用==表示它们是相等的.如果两个引用指向不同的对象,用==表示它们是不相等的,即使它们的内容相同. 运行下面代码:
- leetcode-501. Find Mode in Binary Search Tree
Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred ...
- Python基础(4)_集合、布尔类型
一.集合 集合的作用一:关系运算集合的作用二:去重 定义集合:集合内的元素必须是唯一的:集合内的元素必须是可hash的,也是就不可变类型:集合是无序的 s={'egon',123,'egon','1' ...
- 用 letsencrypt 生成 SSL 证书
letsencrypt 生成 SSL 证书 事先配置好访问域名解析 在nginx 对应虚拟主机添加一个验证区域: 配置 nginx server { listen 80; ... location ~ ...