题目描述 给你一串正整数数列 a1,a2,a3......an 每次删除一个元素 并且输出此时最大连续子串和
首先从前向后删可能比较麻烦些 (每个区间肯定要遍历) ,所以考虑从后向前添元素 ,每次记录最大和 与下一次比较 ,添元素的过程中只需考虑两点
1左边是否添加
2右边是否添加
所以麻烦主要是要去遍历左右两边找和,这里解决的方法是用并差集,记录一个区间的和, 并且更新(好好理解下并差集搜索和更新与线段树,st表,树状数组的区别)
wa了一次 其实意识到了会爆int ,但有个地方还是忘开long long了;
注意代码是离线算法 也就是查询完才输出答案
在线算法 一边查一边输出答案
ac代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e5+3;
int que[MAX];
int find(int x){
if(que[x]==x) return x;
else return find(que[x]);
}
int main(){
// freopen("1.txt","r",stdin);
ios::sync_with_stdio(0);
cin.tie(0);
stack<long long > sta;
int n;
cin>>n;
int a[MAX],b[MAX],vis[MAX];
long long c[MAX];
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
cin>>b[i];
for(int i=1;i<=n;i++)
que[i]=i;
memset(vis,0,sizeof(vis));
memset(c,0,sizeof(c));
long long ans=0;
sta.push(ans);
for(int i=n;i>=2;i--){
vis[b[i]]=1;
int l=b[i]-1,r=b[i]+1;
c[b[i]]=a[b[i]];
if(vis[l]) {
int x=find(l);
que[x]=b[i];
c[b[i]]+=c[x];
}
if(vis[r]) {
int x=find(r);
que[x]=b[i];
c[b[i]]+=c[x];
}
ans=max(c[b[i]],ans);
sta.push(ans);
}
while(!sta.empty()){
cout<<sta.top()<<endl;
sta.pop();
}
}

京公网安备 11010502036488号