CF 722C 并查集 - lotusknight/wiki GitHub Wiki
CF 722C 并查集 freopen("test.txt","r",stdin);
memset 0x3f(合理的正无穷) 0x80(负无穷)
10e9是普通的int的大小
https://blog.csdn.net/l773575310/article/details/52913893
https://blog.csdn.net/yskyskyer123/article/details/52277927
https://blog.csdn.net/yexiaohhjk/article/details/52717934
https://blog.csdn.net/qq_32680617/article/details/53398922
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int n;
int a[200010],b[200010],fa[200010],used[200010];
long long now;
long long ans[200010],f[200010];
int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]); //找到一个子串集合的头
}
void work(int x,int y)
{int fx,fy;
fx=find(x); //x对应的集合的头是fx
fy=find(y); //y对应的集合的头是fy,因为x,y中有一个是新插入的,所以他们两个一定是属于两个集合
fa[fx]=fy; //让fy作为新的头,原来的fx是它的子,这样就合并了两个集合
f[fy]+=f[fx]; //将合并后的集合相加得到合并后的数值
now=max(now,f[fy]);
}
//work 之后,f[fy]是左边的和加上f[fy]的值,也就是它保存了左边字串的和。用最右项代表一个。
////上面这句话不太对,得再缕缕,大概就是并查集。上上面的一段话解释了具体操作
int main()
{int i,j,p;
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
for(i=1;i<=n;i++) scanf("%d",&b[i]);
for(i=1;i<=n;i++) fa[i]=i;
for(i=n;i>=1;i--)
{ ans[i]=now;
p=b[i];
used[p]=1;
f[p]=a[p];
now=max(now,f[p]);
if(used[p-1]) work(p-1,p);
if(used[p+1]) work(p,p+1);
}
for(i=1;i<=n;i++)
printf("%I64d\n",ans[i]);
return 0;
}
//
//
//
//
//
//#include <iostream>
//#include <cstring>
//
//#define MAXSIZE 10000000
//
//using namespace std;
//
//int num,idx,cut;
//uint32_t sum,maxi,now;
//int arr[MAXSIZE];
//int ord[MAXSIZE];
//int temp[MAXSIZE];
//uint32_t res[MAXSIZE];
//
////正向思考很难,所以我决定倒推。每次增加一个点,找连续大于0的最大值。
//
//uint32_t compt(int cut,int idx)
//{
// uint32_t sum = cut;
// int tt = idx;
// while(--tt>=0&&temp[tt]>=0)
// {
// sum += temp[tt];
// }
// tt = idx;
// while(++tt<num&&temp[tt]>=0)
// {
// sum += temp[tt];
// }
// return sum;
//}
//
//int main()
//{
//// memset(temp,-1,sizeof(temp));
//// freopen("test.txt","r",stdin);
// cin >> num;
// for(int i=0; i<num+2; i++)
// temp[i]=-1;
// for(int i = 0; i < num; i++)
// {
// cin >> arr[i];
// sum += arr[i];
//// cout << arr[i] << ' ';
// }
//// cout << endl;
//
// for(int i = 0; i < num; i++)
// {
// cin >> ord[i];
//// cout << "change the " << ord[i] << "th num" << endl;
// }
// for(int i = num-1,j=0; i>=0; i--,j++)
// {
// idx = ord[i]-1;
// cut = arr[idx];
// temp[idx] = arr[idx];
// now = compt(cut,idx);
// maxi = max(maxi,now);
// res[j] = maxi;
// }
// for(int i= num-2; i>=0; i--)
// {
// cout << res[i]<<endl;
// }
// cout<<0<<endl;
//
// return 0;
//}
//#include <iostream>
//
//#define MAXSIZE 100000000
//
//using namespace std;
//
//int num,sum,idx,cut;
//int arr[MAXSIZE];
//int ord[MAXSIZE];
//int res[MAXSIZE];
//
//// delete idx save the num of the left sum
//
//int main()
//{
// freopen("test.txt","r",stdin);
// cin >> num;
// for(int i = 0; i < num; i++){
// cin >> arr[i];
// sum += arr[i];
// cout << arr[i] << ' ';
// }
// res[n]=sum;
// printf("sum is %d.\n",sum);
// cout <<endl;
// for(int i = 0; i < num; i++){
// cin >> ord[i];
// cout << "change the " << ord[i] << "th num" << endl;
// idx = ord[i]-1;
// cut = arr[idx];
// for(int i = idx; arr[idx]>0; idx--){
// res[idx]+=arr[idx];
// }
//
//
// }
// return 0;
//}