算法与数据结构实验题 9.22 破碎的数组
★实验任务
给你一个有n个元素的数组(下标从1开始),现在你要开始破坏这个数组(破坏n次),每破坏一次位置,则会使得这个破坏位置的元素消失,并把数组分成若干字段,问你破坏完一次之后,当前存在的字段中的权值最大为多少(字段权值即为字段中包含未被破坏的元素的权值和)。
★数据输入
输入第一行为一个正整数n。
第二行为n个正整数ai(1<=ai<=10^9),表示初始数组
第三行为n个正整数bi(1<=ai<=n),表示每次破坏的位置
80%的数据 1<=n<=1000.
100%的数据1<=n<=100000.
★数据输出
输出一个正整数,表示当前存在的字段中的权值最大值#
输入示例1
4
1 3 2 5
3 4 1 2
输出示例1
5
4
3
0
输入示例2
5
1 2 3 4 5
4 2 3 5 1
输出示例2
6
5
5
1
0
*Hint
样例一:
第一次破坏下标为3的元素,数组变成了{1,3},{5},权值最大为5,
第二次破坏下标为4的元素,数组变成{1,3},权值最大为4,
思路
倒着处理即可,不要被Hint给迷惑。
#include <cstdio>
#include <stack>
using namespace std;
int a[100001]={0};
bool existed[100001] = {false};
void update(int n){
int i = n, j = n;
if(existed[n-1]){
a[n] += a[n - 1]; }
if(existed[n+1]){
a[n] += a[n + 1]; }
while(existed[--i]!=false);
a[i+1]=a[n];
while(existed[++j]!=false);
a[j-1]=a[n];
//中间的就不更新了,只更新区间两边
}
int main(){
int n;
int max = 0;
stack<int> ri;
stack<int> res;
scanf("%d", &n);
for (int i = 1; i <= n;i++){
scanf("%d", &a[i]);
}
int temp;
for (int i = 0; i < n;i++){
scanf("%d", &temp);
ri.push(temp);
}
while(!ri.empty())
{
res.push(max);
temp = ri.top();
existed[temp] = true;
update(temp);
if(a[temp]>max)
{
max = a[temp];
ri.pop();
}
while(!res.empty())
{
printf("%d\n", res.top());
res.pop();
}
return 0;
}