zoukankan      html  css  js  c++  java
  • 线段树

    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("%lld
    ", 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("%lld
    ", sta.top());
            sta.pop();
        }
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    与灵感之源的vb.net对应的SmartExcel的C#版本
    winform下提高control在UI中的响应速度
    做了一个petoolkit的gui版本,放几张图上来。
    Reflection中对于out类型的获取
    对企业管理软件“代码后”问题的思考
    看了dannyr的java中文类,自己写了一个。
    所有的WMI可以使用的class
    庆祝浪潮集团成为微软在中国的第四家全球战略合作伙伴!(暂时放首页两天)
    一种系统间集成的同步事务异常处理方法和装置
    一种实现多线并行拣选的方法
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/8351387.html
Copyright © 2011-2022 走看看