您的位置:首页 > 其它

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C. Destroying Array 双向链表+反向做+优先队列

2016-10-03 21:55 411 查看
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.

Source

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

My Solution

 双向链表+反向做+优先队列

反向做,按着反的顺序把元素一个一个的添加进去,用priority_queue 维护当前最值,

用双向链表维护当前区间的状态,L[i]表示以i为端点的区间的区间左端点,R[i]表示以i为区间端点的右端点

对于每个点 j, 当只R[i + 1] != 0 时, 右边有区间,可以把两个链表合并成一个, R[i] = R[i + 1], L[i]  = i;

                           当只L[i - 1] != 0 时, 左边有区间,可以把两个链表合并成一个, R[L[i - 1]] = i, R[i] = i, L[i] = L[i - 1]

   当两边都有区间时,先合并一边,再合并另一边最后得到的区间是 [ L[i - 1], R[i + 1] ];

然后根据合并来的区间得到新的区间和,push到priority_queue里,这个和必定比原来分开的子区间大,所以原来的子区间和就留在pq里不用管了。最多维护n个元素

区间和用 map<pair<int, int>, LL> mp,来维护, mp[ii(i, i)] = a[per[i]];, 然后 mp[ii(l, r)]就用来维护新的区间的和,然后push到pq里。

复杂度 O(nlogn)

#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
#include <cstring>
using namespace std;
typedef long long LL;
typedef pair<int, int> ii;
const int maxn = 1e5 + 8;

priority_queue<LL> pq;
map<ii, LL> mp;

LL a[maxn], per[maxn], L[maxn], R[maxn], ans[maxn];

int main()
{
#ifdef LOCAL
freopen("c.txt", "r", stdin);
//freopen("c.out", "w", stdout);
int T = 3;
while(T--){
#endif // LOCAL
ios::sync_with_stdio(false); cin.tie(0);

LL n, l, r, sum;
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
}
for(int i = 1; i <= n; i++){
cin >> per[i];
}

for(int i = n; i > 0; i--){
if(i == n){
L[per
] = per
;
R[per
] = per
;
mp[ii(per
, per
)] = a[per
];
pq.push(a[per
]);
ans
= 0;
}
else{
ans[i] = pq.top();
sum = a[per[i]];
l = per[i], r = per[i];
L[l] = l, R[l] = l;
if(L[per[i]+1] != 0){
L[per[i]] = per[i];
R[per[i]] = R[per[i]+1];
L[R[per[i]+1]] = per[i];
r = R[per[i]];
sum += mp[ii(per[i]+1, r)];
}
if(R[per[i]-1] != 0){
if(R[per[i]] != 0){
R[L[per[i]-1]] = R[per[i]];
L[R[per[i]]] = L[per[i]-1];
l = L[per[i]-1];
sum += mp[ii(l, per[i]-1)];

}
else{
R[L[per[i]-1]] = per[i];
R[per[i]] = per[i];
L[per[i]] = L[per[i]-1];
l = L[per[i]-1];
sum += mp[ii(l, per[i]-1)];
}

}
mp[ii(l, r)] = sum;
pq.push(sum);
}
}

for(int i = 1; i <= n; i++){
cout << ans[i] << "\n";
}
#ifdef LOCAL
memset(L, 0, sizeof L);
memset(R, 0, sizeof R);
mp.clear();
while(!pq.empty()) pq.pop();
cout << endl;
}
#endif // LOCAL
return 0;
}


  Thank you!

                                                                                                           
                                   ------from ProLights 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐