CodeForces722C Destroying Array (线段树)

Posted fang-hao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces722C Destroying Array (线段树)相关的知识,希望对你有一定的参考价值。

luogu  CodeForces

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.

题目描述

给你一个由n个非负整数组成的数列 a1 , a2 ,..., an 。

你将要一个一个摧毁这个数列中的数。并且,现在给你一个由 1 到 n 组成的序列来告诉你每个数被摧毁的时间顺序。

每当一个元素被摧毁时,你需要找到这个当前数列中的未被摧毁的数组成的和最大的连续子序列,另外,如果当前剩余的序列是空的的话,最大和就是0。

输入输出格式

输入格式

第一行包含一个整数n (1 <= n <= 100000) , 代表数列的长度。

第二行包含n个整数 a1 , a2 ,..., an? (0 <= ai? <= 10^9)。

第三行包含一个由1到n的整数组成的序列,代表数被摧毁的顺序。

输出格式

输出有n行,第i行包含一个整数 —— 在第i个操作已经执行完之后,数列中连续的最大和。

说明

第一个样例:

1.第三个数被删除了,现在的数列是 1 3 x 5 ,5由一个数5组成。

2.第四个数被删除了,现在的数列是 1 3 x x ,4由两个数1和3组成。

3.第一个数被删除了,现在的数列是 x 3 x x ,3由一个数3组成。

4.最后一个剩下的数被删除了,现在的数列中没有东西啦,所以答案是0呢!

(自己翻译)

 

解题思路

FBI WARNING :THIS ANSWER IS BULL SHIT!!

 

好吧我们正经做题qwq

我们看到询问最大区间,那么第一反应应该可以想到线段树维护,那我们如何实现快速删除呢?

 

很简单,我们不需要删除。

你想,我们假如要删除一个数,那么我们只需要把他改成-99999999999.....这样一个很小的数,那么我们在统计最大序列是时,不可能把他算进去,对吧? 不然把整个序列都变成负的了23333

所以我们只需要单点修改即可,连查询都不需要写。

维护区间和,最大子序列,从左开头的最大子序列,从右开始的最大子序列,用push_up进行转移就好啦!

ps:注意两个负无穷的数相加的时候特判一下,不要加爆了(雾)。

如果不会用线段树维护最大连续和的童鞋自行百度一下啦~\(≧▽≦)/~

 

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=800400;
 7 const long long INF=-90000000000000LL;
 8 long long ml[maxn],mr[maxn],m[maxn],sum[maxn];
 9 long long n;
10 inline void read(long long &x){
11     x=0; register char ch=getchar();
12     while(ch<0||ch>9)ch=getchar();
13     while(ch>=0&&ch<=9)x=x*10+ch-0,ch=getchar();
14 }
15 inline void push_up(int ID){
16     if(mr[ID<<1]==INF&&ml[ID<<1|1]==INF){
17         m[ID]=max(m[ID<<1],m[ID<<1|1]);
18     }
19     else m[ID]=max(m[ID<<1],max(m[ID<<1|1],mr[ID<<1]+ml[ID<<1|1]));
20     if(sum[ID<<1]==INF&&ml[ID<<1|1]==INF){
21         ml[ID]=max(ml[ID<<1],INF);
22     }
23     else ml[ID]=max(ml[ID<<1],sum[ID<<1]+ml[ID<<1|1]);
24     if(sum[ID<<1|1]==INF&&mr[ID<<1]==INF){
25         mr[ID]=max(mr[ID<<1|1],INF);
26     }
27     else mr[ID]=max(mr[ID<<1|1],sum[ID<<1|1]+mr[ID<<1]);
28     if(sum[ID<<1]==INF&&sum[ID<<1|1]==INF){
29         sum[ID]=INF;
30     }
31     else sum[ID]=sum[ID<<1]+sum[ID<<1|1];
32 }
33 inline void ins(int ID,int nl,int nr,int pos,long long v){
34     if(nl==nr){
35         sum[ID]=ml[ID]=mr[ID]=m[ID]=v;
36         return;
37     }
38     int m=(nl+nr)>>1;
39     if(m>=pos)ins(ID<<1,nl,m,pos,v);
40     else ins(ID<<1|1,m+1,nr,pos,v);
41     push_up(ID);
42 }
43 int main(){
44     read(n);
45     register long long temp;
46     for(register int i=1;i<=n;i++){
47         read(temp);
48         ins(1,1,n,i,temp);
49     }
50     int p;
51     for(register int i=1;i<n;i++){
52         cin>>p;
53         ins(1,1,n,p,INF);
54         long long ans=max(m[1],max(ml[1],mr[1]));
55         cout<<ans<<endl;
56     }
57     cin>>p;
58     cout<<0<<endl;
59 }

 

 

以上是关于CodeForces722C Destroying Array (线段树)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 722C Destroying Array(并查集)*

CodeForces 722C Destroying Array (并查集)

[CF722C] Destroying Array

Codeforces 722C(并查集 + 思维)

CodeForces - 722C(思维+倒着并查集)

Codeforces - 722C 裸区间合并