CodeForces - 722C_Destroying Array 並查集應用

題目大意:給定數組大小n,再給定數組元素(從1~n編號),最後給定數組元素的刪除順序,求執行完每一次刪除操作後,數組的最大連續子段和。

倒着處理,並查集。
(1)初始化數組爲空,倒着加入元素。
(2)每一次加入元素,如果其左右兩邊也加入過了,就與左或者右邊並在一起得到新的數值。當前答案來源於上一次的答案或者本次更新的數值,將兩者取最大值即可。

//並查集,倒着處理
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
const int N = 1e5+10;
ll a[N], ans[N], son[N];
int b[N], fa[N];
bool vis[N];

int findf(int x)
{
    return x==fa[x]?x:fa[x]=findf(fa[x]);
}

void merge_(int x, int y)
{
    int f1 = findf(x);
    int f2 = findf(y);
    if(f1 != f2)
    {
        fa[f2] = f1;
        son[f1] += son[f2];
    }
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
    for(int i = 1; i <= n; ++i) scanf("%d", &b[i]);
    for(int i = 1; i <= n; ++i) fa[i] = i, son[i] = a[i];
    memset(vis, 0, sizeof(vis));
    ans[n] = 0;
    for(int i = n; i > 1; --i)
    {
        int pos = b[i];
        vis[pos] = 1;
        if(vis[pos-1]) merge_(pos-1, pos);
        if(vis[pos+1]) merge_(pos+1, pos);
        ans[i-1] = max(ans[i], son[findf(pos)]);
    }
    for(int i = 1; i <= n; ++i) printf("%lld\n", ans[i]);
    return 0;
}
發佈了111 篇原創文章 · 獲贊 38 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章