#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N=1e5+20;
int fa[N],n;
ll sum[N];//sum[i] i顶点所在的连通块的和
int a[N],del[N];
ll ans[N],res;
bool join[N];//join[i] 点i是否加入
int find(int x)
{
if(x!=fa[x])
{
fa[x]=find(fa[x]);
}
return fa[x];
}
void Union(int x,int y)
{
if(y<=0||y>n) return;
int fx=find(x),fy=find(y);
if(fx!=fy)
{
fa[fx]=fy;
sum[fx]+=sum[fy];
sum[fy]=sum[fx];
res=max(res,sum[fy]);//res递增
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
fa[i]=i;
sum[i]=0;
join[i]=false;
}
for(int i=1;i<=n;i++)
scanf("%d",&del[i]);
res=ans[n]=0;//全del时
for(int i=n;i>=1;i--)//逆序添加,最值递增
{
join[del[i]]=true;
sum[del[i]]=a[del[i]];
if(join[del[i]-1])
Union(del[i],del[i]-1);
if(join[del[i]+1])
Union(del[i],del[i]+1);
ans[i-1]=max(res,sum[del[i]]);//最值要么是以前的连通块或者是新合并的连通快
res=ans[i-1];
}
for(int i=1;i<=n;i++)
cout<<ans[i]<<endl;
return 0;
}
codeforces 722C 并查集好题+逆序处理
最新推荐文章于 2022-03-15 22:53:44 发布