Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)C. Destroying Array(想法题)

传送门

Description

You are given an array consisting of n non-negative integers a1, a2, ..., an.

You are going to destroy integers in the array one by one. Thus, you are given the permutation of integers from 1 to n defining the order elements of the array are destroyed.

After each element is destroyed you have to find out the segment of the array, such that it contains no destroyed elements and the sum of its elements is maximum possible. The sum of elements in the empty segment is considered to be 0.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the length of the array.

The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

The third line contains a permutation of integers from 1 to n — the order used to destroy elements.

Output

Print n lines. The i-th line should contain a single integer — the maximum possible sum of elements on the segment containing no destroyed elements, after first i operations are performed.

Sample Input

41 3 2 53 4 1 2
51 2 3 4 54 2 3 5 1
85 5 4 4 6 6 5 55 2 8 7 1 3 4 6

Sample Output

5430
65510
18161188660

Note

Consider the first sample:

  1. Third element is destroyed. Array is now 1 3  *  5. Segment with maximum sum 5 consists of one integer 5.
  2. Fourth element is destroyed. Array is now 1 3  *   * . Segment with maximum sum 4 consists of two integers 1 3.
  3. First element is destroyed. Array is now  *  3  *   * . Segment with maximum sum 3 consists of one integer 3.
  4. Last element is destroyed. At this moment there are no valid nonempty segments left in this array, so the answer is equal to 0.

思路

题意:

给定一个长度为n的数字序列,每次删除一个数,问剩下的段中和最大的值为多少

题解:

使用multiset存下每次删除的位置,以及每段的和,利用预处理的前缀和,依次更新就好了。注意:multiset容器中有多个相同值的时候,使用erase函数会把所有相同的值都删除,如果只是想删除一个数,那么可以用s.erase(s.find(val))来删除一个值为val的数。

#include<bits/stdc++.h>
using namespace std;
typedef __int64 LL;
const int maxn = 100005;
LL a[maxn],sum[maxn];
multiset<int>pos;
multiset<LL>s;
multiset<int>::iterator front,rear;
multiset<LL>::iterator it; 

int main()
{
	int n,p;
	scanf("%d",&n);
	for (int i = 0;i < n;i++)
	{
		scanf("%I64d",&a[i]);
		sum[i+1] = sum[i] + a[i];
	}
	sum[n+1] = sum[n];
	pos.insert(0),pos.insert(n+1);
	s.insert(sum[n]);
	while (n--)
	{
		scanf("%d",&p);
		pos.insert(p);
		front = rear = pos.find(p);
		front--,rear++;
		s.erase(s.find(sum[*rear-1]-sum[*front]));
		s.insert(sum[*rear-1]-sum[p]);
		s.insert(sum[p-1]-sum[*front]);
		it = s.end();
		--it--;
		cout << *it << endl;
	}
	return 0;
}

  

时间: 2024-12-17 00:38:18

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)C. Destroying Array(想法题)的相关文章

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)(set容器里count函数以及加强for循环)

题目链接:http://codeforces.com/contest/722/problem/D 1 #include <bits/stdc++.h> 2 #include <iostream> 3 #include <queue> 4 #include <stdio.h> 5 #include <string.h> 6 #include <algorithm> 7 #include <string> 8 #include

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)

A题,水题,不过我写的时候少考虑了一个细节导致WA了一发. B题,水题,判断一行内元音字母的个数是不是等于p[i]即可. C题,好题,反过来思考,用并查集离线处理.每次如果能合并就合并并更新答案即可.代码如下: 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <iostream> 5 #include <queue> 6 using name

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array -- 逆向思维

原题中需要求解的是按照它给定的操作次序,即每次删掉一个数字求删掉后每个区间段的和的最大值是多少. 正面求解需要维护新形成的区间段,以及每段和,需要一些数据结构比如 map 和 set. map<int, LL>interval2Sum来维护区间段(u->v),mulitset<LL>sum 来维护最大值.那么每次删除操作后,都需要去interval2Sum中找到对应区间,然后erase掉, 重新生成left -> delId -> right两个区间段,最后在ma

C. Destroying Array 并查集/线段树 Intel Code Challenge Elimination Round (Div. 1 + Div. 2, combined)

题目大意就是给一个初始数组,每次删除一个点,问你剩下的连续的那些点中,最大的和是多少 2种做法 第一种是离线并查集  (这里是不会用那个res[]数组,将子的权值挪给父亲那里. 第二种是线段树区间合并.(练手 ///线段树 1 #include <algorithm> 2 #include <stack> 3 #include <istream> 4 #include <stdio.h> 5 #include <map> 6 #include &

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C. Ray Tracing

C. Ray Tracing There are k sensors located in the rectangular room of size n × m meters. The i-th sensor is located at point (xi, yi). All sensors are located at distinct points strictly inside the rectangle. Opposite corners of the room are located

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)

C 模拟 题意:给的是一个矩形,然后√2 的速度走,如果走到边上就正常反射,走到角上,暂停反射,我们知道要不循环要不暂停,记录走到的点最短时间 /************************************************************************* > File Name: c.cpp > Author: opas_chenxin > Mail: [email protected] > Created Time: 2016年10月08日

codeforces Intel Code Challenge Final Round (div.1 + div.2 combined)

比赛水掉3题rk559 rating+115 赛后切掉C n年没打cf了终于又重新变蓝了,果然太弱... 1.A题  Checking the Calendar 给定两个星期几,问是否可能分别是两个月的第一天. 水题暴力枚举月份 #include<cstdio> #include<cstring> #include<cstdlib> #include<vector> #include<algorithm> #include<function

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) A

Description You are given names of two days of the week. Please, determine whether it is possible that during some non-leap year the first day of some month was equal to the first day of the week you are given, while the first day of the next month w

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)D Dense Subsequence

传送门:D Dense Subsequence 题意:输入一个m,然后输入一个字符串,从字符串中取出一些字符组成一个串,要求满足:在任意长度为m的区间内都至少有一个字符被取到,找出所有可能性中字典序最小的情况,并按字典序输出 思路:字典序 例如 aaaaaaab < ab  也就是说,如果满足要求的取法中取到了b 那么所有的a都应该被取到,这样才可以保证字典序最小,那么也就是说在26个字母中找到一定要被取的最大字母,然后再确定最大的字母的个数,比它小的全部要取 AC代码: 1 #include