题目描述 给你一串正整数数列 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(); } }