题干:

给定一个有n个数的序列a1,a2, ..., an

你每次可以将序列中一个数删去,剩下的数会被分割为一段一段连续的数列

给定一个删除数的顺序,问在每次删除之后,剩下的连续的数列中,数列和的最大值为多少

Input

第一行输入仅有一个正整数n(1<=n<=100000)

第二行包括n个整数a1,a2, ..., an(0<=ai<=1,000,000,000)

第三行为n个正整数的一个全排列,为删除元素的顺序。

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:

  1. Third element is destroyed. Array is now 1 3  *  5. Segment with maximum sum 5consists of one integer 5.
  2. Fourth element is destroyed. Array is now 1 3  *   * . Segment with maximum sum 4consists of two integers 1 3.
  3. First element is destroyed. Array is now  *  3  *   * . Segment with maximum sum 3consists 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.

解题报告:

  倒着考虑操作,并查集维护最大值即可。具体就是如果当前操作位置idx,如果左边已经操作过,那就可以想做合并,同理可以向右合并,注意a[i]可以为0,所以不能用sum数组来判断是否出现过,而应该新开一个数组ok来记录。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
int n,op[MAX],f[MAX];
ll a[MAX],sum[MAX],ans[MAX],mx;
int getf(int v) {
return f[v] == v ? v : f[v] = getf(f[v]);
}
void merge(int u,int v) {
int t1 = getf(u),t2 = getf(v);
if(t1 == t2) return;
f[t2] = t1;
sum[t1] += sum[t2];
mx = max(mx,sum[t1]);
}
bool ok[MAX];
int main()
{
cin>>n;
for(int i = 1; i<=n; i++) scanf("%lld",a+i),f[i] = i;
for(int i = 1; i<=n; i++) scanf("%d",op+i);
for(int i = n; i>=1; i--) {
sum[op[i]] = a[op[i]];ok[op[i]]=1;
mx = max(mx,sum[op[i]]);
if(ok[op[i]+1] != 0) merge(op[i],op[i]+1);
if(ok[op[i]-1] != 0) merge(op[i],op[i]-1);
ans[i]=mx;
}
for(int i = 2; i<=n; i++) printf("%lld\n",ans[i]);
puts("0");
return 0 ;
}