6159. 删除操作后的最大子段和 - 力扣(LeetCode)
本来是正向的思路,用二分找到删除点所在的区间,然后从set种删除原区间加入断开的两个区间和。不过有点麻烦,时间不够就没写出来。但是这题逆向的思考,用并查集每次添加一个集合,同时判断这个数有没有相邻集合,有就合并。就快多了
#define ll long long
class Solution {
public:
vector<int>pre;//用一个父节点表示集合
vector<ll>sum;//集合的和
int fnd(int k){
return pre[k]==k?k:pre[k]=fnd(pre[k]);
}
vector<long long> maximumSegmentSum(vector<int>& nums, vector<int>& removeQueries) {
vector<long long>ans;
int n=nums.size();
for(int j=0;j<n;j++){
pre.push_back(j);
sum.push_back(0ll);
}
ll res=0;
for(int j=removeQueries.size()-1;j>=0;j--){//倒序,删除操作改为添加操作,合并区间和
int x=removeQueries[j];
sum[x]=nums[x];
for(int j=x-1;j<=x+1;j+=2){
if(j>=0 and j<n and sum[j]!=0){//有相邻集合,合并
sum[x]+=sum[fnd(j)];//加上相邻集合的和
pre[fnd(j)]=x;
}
}
ans.push_back(res);
res=max(res,sum[x]);
}
reverse(ans.begin(),ans.end());
return ans;
}
};