Codeforces-808D Array Division 【multiset】

Description

Vasya has an array a consisting of positive integer numbers. Vasya wants to divide this array into two non-empty consecutive parts (the prefix and the suffix) so that the sum of all elements in the first part equals to the sum of elements in the second part. It is not always possible, so Vasya will move some element before dividing the array (Vasya will erase some element and insert it into an arbitrary position).

Inserting an element in the same position he was erased from is also considered moving.

Can Vasya divide the array after choosing the right element to move and its new position?

Input

The first line contains single integer n (1?≤?n?≤?100000) — the size of the array.

The second line contains n integers a1,?a2... an (1?≤?ai?≤?109) — the elements of the array.

Output

Print YES if Vasya can divide the array after moving one element. Otherwise print NO.

Examples

Input

31 3 2

Output

YES

Input

51 2 3 4 5

Output

NO

Input

52 2 3 4 5

Output

YES

Note

In the first example Vasya can move the second element to the end of the array.

In the second example no move can make the division possible.

In the third example Vasya can move the fourth element by one position to the left.



题解:

题意是给定一个数列,移动0或1个数字,使数列能从某个位置分开前后两半的和相等。我们可以假象有个隔板从左向右扫,每次两边的和的差值为x,若能找到某一边(看那边大)的一个数为x/2,则将它放到另一边满足条件。扫一遍O(n),数据是无序的,如果暴力查找则总复杂度O(n^2)无法承受,我们可以维护两个平衡树做到O(nlogn),这里我们发现完全可以用STL的multiset代替。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define INF 0x3f3f3f3f
 4 #define M(a, b) memset(a, b, sizeof(a))
 5 const int N = 100000 + 5;
 6 long long a[N];
 7 multiset<long long> s1, s2;
 8 multiset<long long>::iterator it;
 9
10 int main() {
11     ios::sync_with_stdio(false);
12     int n;
13     while (cin >> n) {
14         s1.clear(); s2.clear();
15         long long sum = 0;
16         for (int i = 1; i <= n; ++i) cin >> a[i], sum += a[i], s2.insert(a[i]);
17         if (sum & 1) {cout << "NO\n"; continue;}
18         long long sum1 = 0, sum2 = sum;
19         if (s2.count(sum/2)) {cout << "YES\n"; continue;}
20         bool flag = 0;
21         long long temp;
22         for (int i = 1; i <= n; ++i) {
23             if (sum1 == sum2) {flag = 1; break;}
24             if (sum1 < sum2) {
25                 temp = sum2-sum1;
26                 if (temp%2==0 && s2.count(temp/2)) {flag = 1; break;}
27             }
28             else {
29                 temp = sum1-sum2;
30                 if (temp%2==0 && s1.count(temp/2)) {flag = 1; break;}
31             }
32             sum1 += a[i]; s1.insert(a[i]);
33             sum2 -= a[i]; it = s2.find(a[i]); s2.erase(it);
34         }
35         if (flag) cout << "YES\n";
36         else cout << "NO\n";
37
38     }
39
40     return 0;
41 }
时间: 2024-10-11 05:03:41

Codeforces-808D Array Division 【multiset】的相关文章

【multiset】hdu 5349 MZL&#39;s simple problem

[multiset]hdu 5349 MZL's simple problem 题目链接:hdu 5349 MZL's simple problem 题目大意 n次操作,插入元素.删除最小元素.查询最大元素并输出. C++STL的multiset的使用 set--多元集合(元素不可重复),multiset--可重复元素的多元集合 多元集合(MultiSets)和集合(Sets)相像,只不过支持重复对象.(具体用法请参照set容器) set和multiset内部是以平衡二叉树实现的: 从内部数据结

C# Array类 【温故而知新】

简单的数组知识代码及注释讲解 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace Array类 { class Program { static void Main(string[] args) { //Array是一个抽象类,不能使用构造函数来创建数组 //创建数组 Array arr = Array.CreateInst

[CodeForces - 1225D]Power Products 【数论】 【分解质因数】

[CodeForces - 1225D]Power Products [数论] [分解质因数] 题目描述 Time limit 2000 ms Memory limit 524288 kB Source Technocup 2020 - Elimination Round 2 Tags hashing math number theory *1900 Site https://codeforces.com/problemset/problem/1225/D 题面 Example Input 6

【贪心】【multiset】Tinkoff Challenge - Final Round (Codeforces Round #414, rated, Div. 1 + Div. 2) C. Naming Company

考虑两个人,先把各自的集合排个序,丢掉一半,因为比较劣的那一半一定用不到. 然后贪心地放,只有两种决策,要么把一个最优的放在开头,要么把一个最劣的放在结尾. 如果我的最优的比对方所有的都劣(或等于),我就把我最劣的往结尾放.否则我把我最优的往开头放. 用multiset维护两人的集合即可. #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace

【set】【multiset】Codeforces Round #484 (Div. 2) D. Shark

题意:给你一个序列,让你找一个k,倘若把大于等于k的元素都标记为不可用,那么剩下的所有元素形成的段的长度相同,并且使得段的数量尽量大.如果有多解,输出k尽量小的. 把元素从大到小排序插回原位置,用一个set维护前驱后继,相当于删除一个原有的段,然后将这个段切成两半,产生两个新的段.维护这次操作后所有段的长度以及各种长度的出现次数(用multiset),一旦合法,就尝试更新答案. #include<cstdio> #include<algorithm> #include<set

Hdoj 4302 Holedox Eating 【multiset】

Holedox Eating Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3430 Accepted Submission(s): 1178 Problem Description Holedox is a small animal which can be considered as one point. It lives in a s

【尺取法】【Multiset】bzoj1342 [Baltic2007]Sound静音问题

O(n)地枚举所有长度为k的段,每次暴力转移. 转移的时候只是从最后插入一个数,从前面删去一个数. 计算的时候要取当前的max和min. 用multiset(∵元素是可重的)以上这些操作都是O(logn)的. 1 #include<cstdio> 2 #include<set> 3 using namespace std; 4 multiset<int>S; 5 multiset<int>::iterator it; 6 int n,m,limit; boo

HZAU 18——Array C——————【贪心】

18: Array C Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 586  Solved: 104[Submit][Status][Web Board] Description Giving two integers  and  and two arrays  and  both with length , you should construct an array  also with length  which satisfied: 1.0

CodeForces 666B. World Tour【BFS】

题目链接 http://codeforces.com/problemset/problem/666/B 思路 给你一张有向图,叫你给出四个点的序列,使得这四个点依次间的最短路之和最大. n有3000,直接枚举四个点肯定超时,所以枚举b.c两个点,然后BFS预处理出能到b的最远的3个点,和c能到的最远的3个点. 之所以是3个点是因为,有可能备选点会和已定点重合,例如abc都定好了,然后d的备选是a.b,那就漏情况了,所以要备选3个点. AC代码 #include <iostream> #incl