我是靠谱客的博主 单薄钻石,最近开发中收集的这篇文章主要介绍线段树 - 区间合并,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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.

Example
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
 
题目分析 : 题意是很好懂得,每次删除一个数问你整个区间连续的和最大的是多少 ?
思路分析 : 刚比赛的比赛,想的是线段树的区间合并,然后一顿写啊写,仔细回想之前的线段树区间合并, 写了几发一直WA , 后来读下了题,感觉可能报 LONG LONG ,改了下就A了,赛后查了翻题解,发现可以用并查集在加离线处理的想法,搞了搞就直接过了。
 
const int eps = 1e5+5;
const int maxn = 0x3f3f3f3f;
#define ll long long
#define lson k<<1
#define rson k<<1|1

ll n;
struct node
{
    ll l, r;
    ll lm, rm, sm;
    ll lf, rf; 
}t[eps<<2];

void pushup(ll k){
    t[k].lm = t[lson].lm;
    t[k].rm = t[rson].rm;
    t[k].sm = max(t[lson].sm, t[rson].sm);
    t[k].lf = t[lson].lf;
    t[k].rf = t[rson].rf;
     
    if (t[lson].lf == (t[lson].r - t[lson].l + 1) && t[rson].lf != -1 ) {
        t[k].lm += t[rson].lm;
        t[k].lf += t[rson].lf;
    }
    if (t[rson].rf == (t[rson].r - t[rson].l + 1) && t[lson].rf != -1 ) {
        t[k].rm += t[lson].rm;
        t[k].rf += t[lson].rf;
    }
    if (t[lson].rf != -1 && t[rson].lf != -1)
        t[k].sm = max(t[k].sm, t[lson].rm + t[rson].lm);
}

void build(ll l, ll r, ll k){
    t[k].l = l;
    t[k].r = r;
    t[k].lf = t[k].rf = r-l+1;
    
    ll x;
    if (l == r){
        scanf("%lld", &x);
        t[k].lm = t[k].rm = t[k].sm = x;
        return;
    }
    ll m = (l + r) >> 1;
    build(l, m, lson);
    build(m+1, r, rson);
    pushup(k);
}

void update(ll x, ll k){
    if (t[k].l == t[k].r){
        t[k].lf = t[k].rf = -1;
        t[k].lm = t[k].rm = t[k].sm = 0;
        return;
    }
    ll m = (t[k].l + t[k].r) >> 1;
    if (x <= m) update(x, lson);
    if (x > m) update(x, rson);
    pushup(k);
}

int main() {
    ll x;
    scanf("%lld", &n);
    build(1, n, 1);
    for(ll i = 1; i <= n; i++){
        scanf("%lld", &x);
        update(x, 1);
        printf("%lldn", t[1].sm);
    }

    return 0;
}

 

并查集 :

const int eps = 1e5+5;
#define ll long long

ll a[eps], b[eps], c[eps];
ll f[eps];
ll s[eps];
ll n;
stack<ll>sta;

ll find(ll x){
    return x==f[x]?x:find(f[x]);
}

int main() {
    cin >> n;    
    
    for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    for(int i = 1; i <= n; i++) scanf("%lld", &b[i]);
    
    memset(c, -1, sizeof(c));
    memset(f, -1, sizeof(f));
    ll ans = 0;
    c[b[n]] = a[b[n]];
    f[b[n]] = b[n];
    s[b[n]] = a[b[n]];
    sta.push(ans); 
    ans += c[b[n]]; 
    
    for(ll i = n-1; i >= 1; i--){
        c[b[i]] = a[b[i]];
        f[b[i]] = b[i];
        s[b[i]] = a[b[i]];
        sta.push(ans); 
        if (c[b[i]-1] != -1){
            ll fx = find(b[i]-1);
            f[b[i]] = fx;
            s[fx] += a[b[i]];
            ans = max(ans, s[fx]);
        }
        if (c[b[i]+1] != -1){
            ll f1 = find(b[i]+1);
            ll f2 = find(b[i]);
            f[f1] = f2;
            s[f2] += s[f1];
            ans = max(ans, s[f2]);
        }
        ans = max(ans, s[b[i]]);  
    }
    while(!sta.empty()) {
        printf("%lldn", sta.top());
        sta.pop();
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/ccut-ry/p/8351387.html

最后

以上就是单薄钻石为你收集整理的线段树 - 区间合并的全部内容,希望文章能够帮你解决线段树 - 区间合并所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部