1. 程式人生 > >【CodeForces】722C Destroying Array (線段樹)

【CodeForces】722C Destroying Array (線段樹)

mes HR oid lan 區間和 contain specific HA ref

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個非負整數組成的數列 a1a2 ,..., an

你將要一個一個摧毀這個數列中的數。並且,現在給你一個由 1 到 n 組成的序列來告訴你每個數被摧毀的時間順序。

每當一個元素被摧毀時,你需要找到這個當前數列中的未被摧毀的數組成的和最大的連續子序列,另外,如果當前剩余的序列是空的的話,最大和就是0。

輸入輸出格式

輸入格式

第一行包含一個整數n (1 <= n <= 100000) , 代表數列的長度。

第二行包含n個整數 a1a2 ,..., 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 }

【CodeForces】722C Destroying Array (線段樹)