codeforces 722C Destroying Array

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011528035/article/details/52723289

题意:每次破坏一个数  求当前连续区间和最大的那个值是多少


思路:因为每个数都大于0 所以只要记录每个区间最右边的数的和 就可以了 每次破坏都有可能会产生两个区间 所以只要判断一下就可以了


ps:其实用stl的lowerbound 会更方便  结果写了三个线段树 

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;

#define N 100100
#define LL long long

LL sum[N];
int a[N];
LL c[N*4];

int v1[N*4];
int v2[N*4];

int vis[N];
int n;
void build(int l,int r,int tt)
{
    if(l==r)
    {
        v2[tt]=n+1;
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,tt*2);
    build(mid+1,r,tt*2+1);
    v2[tt]=min(v2[tt*2],v2[tt*2+1]);
}

void updatev(int l,int r,int k,int tt)
{
    if(l==r)
    {

        v1[tt]=k;
        v2[tt]=k;

        return ;
    }
    int mid=(l+r)/2;
    if(mid<k)
    {
        updatev(mid+1,r,k,tt*2+1);
    }
    else
    {
        updatev(l,mid,k,tt*2);
    }
    v1[tt]=max(v1[tt*2],v1[tt*2+1]);
    v2[tt]=min(v2[tt*2],v2[tt*2+1]);
}


int queryl(int l,int r,int tt,int x,int y)
{
    if(l==x&&r==y)
    {
        return v1[tt];
    }
    int mid=(l+r)/2;
    if(mid<x)
    {
        return queryl(mid+1,r,tt*2+1,x,y);
    }
    else if(y<=mid)
    {
        return queryl(l,mid,tt*2,x,y);
    }
    else
        return max(queryl(l,mid,tt*2,x,mid),queryl(mid+1,r,tt*2+1,mid+1,y));
}

int queryr(int l,int r,int tt,int x,int y)
{
    if(l==x&&r==y)
    {
        return v2[tt];
    }
    int mid=(l+r)/2;
    if(mid<x)
    {
        return queryr(mid+1,r,tt*2+1,x,y);
    }
    else if(y<=mid)
    {
        return queryr(l,mid,tt*2,x,y);
    }
    else
        return min(queryr(l,mid,tt*2,x,mid),queryr(mid+1,r,tt*2+1,mid+1,y));
}


void update(int l,int r,int k,int tt,LL x)
{
    if(l==r)
    {
        c[tt]=x;
        return ;
    }
    int mid=(l+r)/2;
    if(mid<k)
    {
        update(mid+1,r,k,tt*2+1,x);
    }
    else
    {
        update(l,mid,k,tt*2,x);
    }
    c[tt]=max(c[tt*2],c[tt*2+1]);
}

int main()
{
    int x;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }

    build(1,n,1);
    update(1,n,n,1,sum[n]);
    int pos;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        update(1,n,x,1,0);
        updatev(1,n,x,1);
        if(x>1)
        {
            pos=queryl(1,n,1,1,x-1);
            if(pos!=x-1)
            {
                update(1,n,x-1,1,sum[x-1]-sum[pos]);
            }
        }
        if(x<n)
        {
            pos=queryr(1,n,1,x+1,n);
            if(pos!=x+1)
            {
                update(1,n,pos-1,1,sum[pos-1]-sum[x]);
            }
        }
        printf("%lld\n",c[1]);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/u011528035/article/details/52723289