C. Destroying Array ###K //K
题目链接:https://codeforces.ml/contest/722/problem/C
题意:给定 一个数组,查询每次删除掉某个位置后 最大的子区间和为多少
思路: 可以用线段树维护区间最大值做,每次只需要单点删除, 注意别爆ll
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int maxn =1e5+10; 6 const int mod=1e9+7; 7 int a[maxn]; 8 int p[maxn]; 9 10 struct ac 11 { 12 int l,r; 13 ll max1,suf,pre,sum; 14 void update(ll v) 15 { 16 max1=pre=suf=sum=v; 17 } 18 }; 19 ac tree[maxn*4]; 20 21 void pushup(int x) 22 { 23 if(tree[x<<1].sum+tree[x<<1|1].sum>=0) 24 tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum; 25 else 26 tree[x].sum=-1e18; 27 tree[x].max1=max({tree[x<<1].max1,tree[x<<1|1].max1,tree[x<<1].suf+tree[x<<1|1].pre}); 28 tree[x].pre=max(tree[x<<1].pre,tree[x<<1].sum+tree[x<<1|1].pre); 29 tree[x].suf=max(tree[x<<1|1].suf,tree[x<<1].suf+tree[x<<1|1].sum); 30 } 31 32 void build(int x,int l,int r) 33 { 34 tree[x].l=l,tree[x].r=r; 35 if(l==r) 36 { 37 tree[x].update(a[l]); 38 } 39 else 40 { 41 int mid=(l+r)/2; 42 build(x<<1,l,mid); 43 build(x<<1|1,mid+1,r); 44 pushup(x); 45 } 46 } 47 48 void update(int x,int pos,ll v) 49 { 50 int L=tree[x].l,R=tree[x].r; 51 if(L==R) 52 { 53 tree[x].update(v); 54 } 55 else 56 { 57 int mid=(L+R)/2; 58 if(pos<=mid) update(x<<1,pos,v); 59 if(pos>mid) update(x<<1|1,pos,v); 60 pushup(x); 61 } 62 } 63 64 65 int main() 66 { 67 ios::sync_with_stdio(false); 68 cin.tie(0); 69 int n; 70 cin>>n; 71 for(int i=1;i<=n;i++) 72 { 73 cin>>a[i]; 74 } 75 for(int i=1;i<=n;i++) 76 { 77 cin>>p[i]; 78 } 79 80 build(1,1,n); 81 //cout<<tree[1].max1<<" 2"<<'\n'; 82 for(int i=1;i<=n;i++) 83 { 84 update(1,p[i],-1e18); 85 cout<<max(0ll,tree[1].max1)<<'\n'; 86 } 87 88 89 90 91 92 93 }
也可以用并查集做, 用并查集的话要反向考虑 把删除操作转化成添加操作来考虑 然后每次和左右两边的合并即可
1 #include <bits/stdc++.h> 2 #define double long double 3 #define lb long double 4 #define ll long long 5 #define pi pair<int,int> 6 #define fi first 7 #define sc second 8 #define pb push_back 9 using namespace std; 10 const int maxn=1e5+10; 11 12 ll sum[maxn]; 13 int f[maxn]; 14 int n; 15 int c[maxn]; 16 int st[maxn]; 17 18 int find1(int x) 19 { 20 if(x==f[x]) return x; 21 return f[x]=find1(f[x]); 22 } 23 24 25 26 int main() 27 { 28 ios::sync_with_stdio(0); 29 cin.tie(0); 30 cin>>n; 31 for(int i=1;i<=n;i++) cin>>sum[i],f[i]=i; 32 for(int i=1;i<=n;i++) cin>>c[i]; 33 ll mx=0; 34 vector<ll>ans; 35 for(int i=n;i>=1;i--) 36 { 37 ans.pb(mx); 38 int x=c[i]; 39 int l=x-1,r=x+1; 40 int t=find1(x); 41 st[x]=1; 42 if(l>=1&&st[l]) 43 { 44 int tl=find1(l); 45 f[tl]=t; 46 sum[t]+=sum[tl]; 47 } 48 if(r<=n&&st[r]) 49 { 50 int tr=find1(r); 51 f[tr]=t; 52 sum[t]+=sum[tr]; 53 } 54 mx=max(mx,sum[t]); 55 } 56 reverse(ans.begin(),ans.end()); 57 for(auto &v:ans) cout<<v<<'\n'; 58 59 60 61 62 }

浙公网安备 33010602011771号