您的位置:首页 > 其它

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

2016-10-02 00:37 471 查看
大体题意:

给你n 个数字,告诉你破坏每个数字的顺序,每次破坏后你要求一个线段,使得线段不包含破坏的点,并且线段上的值和最大?

思路:

正着删除感觉不好处理,就反过来求了,相当于从一个空序列往上面添加数值,加一次,求一次线段的最大和,在加之前,我们可以先定义一个变量Max 表示之前的操作所得到的最大线段和,然后和加入后进行比较!

加入某个值后,用了并查集进行处理,令c[i]是 i 这个点的权值,那么先判断i+1的位置,如果有值的话,就把i+1这一系列线段加到i位置上,在判断i-1位置,相当于把位置向小位置上并!

有个坑,自己没有注意到,求和时会爆int,开long long

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 10;
typedef long long ll;

vector<ll>ans;
int a[maxn];
int fa[maxn];
int ord[maxn];
int b[maxn];
ll c[maxn];
int find(int x){
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void add(int x,int y){
if (x > y)swap(x,y);
int xx = find(x);
int yy = find(y);
if (xx != yy){
fa[yy] = xx;
}
}
int main(){
int n;
scanf("%d",&n);
memset(b,-1,sizeof b);
for (int i = 0; i <= n; ++i)fa[i] = i;
for (int i = 1; i <= n; ++i){
scanf("%d",&a[i]);

}
for (int i = 1; i <= n; ++i){
scanf("%d",&ord[i]);

}
ans.push_back(0);
ll Max = -1;
for (int i = n; i >= 1; --i){
int pos=ord[i];
b[pos] = a[pos];
ll t;
c[pos] += a[pos];
t = a[pos];
if (b[pos+1] != -1){
add(pos,pos+1);
c[pos] += c[pos+1];
t = c[pos];
}
if (b[pos-1] != -1){
int fa = find(pos-1);
add(fa,pos);
c[fa] += c[pos];
t = c[fa];
}
if (t > Max){
Max = t;
}
ans.push_back(Max);

}
reverse(ans.begin(),ans.end());
int len = ans.size();
for (int i = 1; i < len; ++i){
printf("%I64d\n",ans[i]);

}
// printf("\n");
return 0;
}


C. Destroying Array

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

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.

Examples

input
4
1 3 2 5
3 4 1 2


output
5
4
3
0


input
5
1 2 3 4 5
4 2 3 5 1


output
6
5
5
1
0


input
8
5 5 4 4 6 6 5 5
5 2 8 7 1 3 4 6


output
18
16
11
8
8
6
6
0


Note

Consider the first sample:

Third element is destroyed. Array is now 1 3  *  5. Segment with maximum sum 5 consists
of one integer 5.

Fourth element is destroyed. Array is now 1 3  *   * . Segment with maximum sum 4 consists
of two integers 1 3.

First element is destroyed. Array is now  *  3  *   * . Segment with maximum sum 3 consists
of one integer 3.

Last element is destroyed. At this moment there are no valid nonempty segments left in this array, so the answer is equal to 0.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐