【CodeForces 722C --- Destroying Array】思维+并查集

【CodeForces 722C --- Destroying Array】思维+并查集

题目来源:点击进入【CodeForces 722C — 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

4
1 3 2 5
3 4 1 2

Sample Output

5
4
3
0

解题思路

本题如果正向直接做的话较为麻烦。
但是我们可以逆向来做,如果逆向来做的话,删除某个值就变成了增加某个值。
每次添加一个数,只有可能把他左边或右边的那两个数连接起来,所以用一个标记来判断相邻的两个数是否在之前已被添加,如果被添加,用并查集把这两个点合并,然后判断之前的最大值和合并后区间的最大值,并更新最大值。

AC代码:

#include 
#include 
using namespace std;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
typedef long long ll;
const int MAXN = 1e5+5;
int arr[MAXN],pre[MAXN],ix[MAXN];
ll sum[MAXN],ans[MAXN];
bool vis[MAXN];

int _find(int x)
{
     
    if(x==pre[x]) return x;
    return pre[x]=_find(pre[x]);
}

void unite(int x,int y)
{
     
    int dx=_find(x);
    int dy=_find(y);
    if(dx==dy) return;
    pre[dx]=dy;
    sum[dy]+=sum[dx];
}

int main()
{
     
    SIS;
    ll n,mx=0;
    cin >> n;
    for(int i=1;i<=n;i++) 
        cin >> arr[i],pre[i]=i,sum[i]=arr[i];
    for(int i=0;i<n;i++)
        cin >> ix[i];
    for(int i=n-1;i>=0;i--)
    {
     
        int x=ix[i];
        ans[i]=mx;
        vis[x]=true;
        if(x!=1 && vis[x-1]) unite(x-1,x);
        if(x!=n && vis[x+1]) unite(x,x+1);
        mx=max(mx,sum[_find(x)]);
    }
    for(int i=0;i<n;i++)
        cout << ans[i] << endl;
    return 0;
}

你可能感兴趣的:(ACM,CodeForces722C,DestroyingArray,思维,并查集)