给一段序列,给你去掉所有数字的顺序,输出每去掉一个数,当前联通的子序列的最大值。

倒着来,每次插入一个数,然后求联通的最大值,线段树每个节点标记一下,区间的左右是否插入了数字,还有如果有数字从左边/右边开始连续子序列的值,还有这个节点的区间是否连续。

 #include <cstdio>

 #include <algorithm>

 using namespace std;

 typedef long long LL;

 const int maxn=;

 int n;

 int i;

 int a[maxn+];

 int b[maxn+];

 LL res[maxn+];

 struct node{
int l,r;
LL sum;
int lflag,rflag;
LL lval,rval;
bool f;
}tree[maxn*+]; void push_up(int id){
int llf=tree[id<<].lflag;
int lrf=tree[id<<].rflag;
int rlf=tree[(id<<)+].lflag;
int rrf=tree[(id<<)+].rflag;
if(lrf&&rlf){
tree[id].sum=max(max(tree[id<<].rval+tree[(id<<)+].lval,tree[id<<].sum),tree[(id<<)+].sum);
tree[id].lflag=llf;
tree[id].rflag=rrf;
if(llf){
if(tree[id<<].f)
tree[id].lval=tree[id<<].lval+tree[(id<<)+].lval;
else tree[id].lval=tree[id<<].lval;
} else {
tree[id].lval=;
}
if(rrf){
if(tree[(id<<)+].f){
tree[id].rval=tree[(id<<)].rval+tree[(id<<)+].rval;
}
else tree[id].rval=tree[(id<<)+].rval;
} else {
tree[id].rval=;
}
tree[id].f=tree[(id<<)].f&&tree[(id<<)+].f;
}else if(!lrf||!rlf){
if(tree[id<<].sum>tree[(id<<)+].sum){
tree[id].sum=tree[id<<].sum;
tree[id].lflag=llf;
tree[id].rflag=rrf;
if(!llf)
tree[id].lval=;
else tree[id].lval=tree[id<<].lval;
if(!rrf)
tree[id].rval=;
else
tree[id].rval=tree[(id<<)+].rval;
tree[id].f=;
} else if(tree[id<<].sum<tree[(id<<)+].sum){
tree[id].sum=tree[(id<<)+].sum;
tree[id].lflag=llf;
tree[id].rflag=rrf;
if(!llf)
tree[id].lval=;
else tree[id].lval=tree[id<<].lval;
if(!rrf)
tree[id].rval=;
else
tree[id].rval=tree[(id<<)+].rval;
tree[id].f=;
} else if(tree[id<<].sum==tree[(id<<)+].sum){
tree[id].sum=tree[id<<].sum;
tree[id].lflag=llf;
tree[id].rflag=rrf;
if(!llf)
tree[id].lval=;
else tree[id].lval=tree[id<<].lval;
if(!rrf)
tree[id].rval=;
else
tree[id].rval=tree[(id<<)+].rval;
tree[id].f=;
} }
} void build(int id,int l,int r){
if(l==r){
tree[id].l=tree[id].r=l;
tree[id].sum=;
tree[id].lflag=tree[id].rflag=;
tree[id].lval=tree[id].rval=;
tree[id].f=;
return ;
}
int mid=(l+r)>>;
build(id<<,l,mid);
build((id<<)+,mid+,r);
push_up(id);
} void update(int id,int l,int r,int x,int val){
if(l==r){
tree[id].sum+=(LL)val;
tree[id].lflag=tree[id].rflag=;
tree[id].lval=tree[id].rval=val;
tree[id].f=;
return ;
}
int mid=(l+r)>>;
if(x<=mid){
update(id<<,l,mid,x,val);
} else {
update((id<<)+,mid+,r,x,val);
}
push_up(id);
} int main()
{
scanf("%d",&n);
build(,,n);
for(i=;i<=n;i++){
scanf("%d",&a[i]);
}
for(i=;i<=n;i++){
scanf("%d",&b[i]);
}
for(i=n;i>=;i--){
update(,,n,b[i],a[b[i]]);
res[i]=tree[].sum;
}
for(int i=;i<=n+;i++){
printf("%I64d\n",res[i]);
}
return ;
}

codeforces772C的更多相关文章

随机推荐

  1. SpringBoot_Exception_01_No plugin found for prefix 'spring-boto' in the current project

    一.异常现象 spingbott项目在eclipse中执行maven命令:spring-boot:run, 出现异常: No plugin found for prefix 'spring-boto' ...

  2. hdu 6103(Kirinriki)

    题目链接:Kirinriki 题目描述: 找两个不重叠的字符串A,B. 使得dis(A,B)<=m;\(dis(A,B)= \sum _{i=0}^{n-1} \left | A_i-B_{n- ...

  3. hdu-5778 abs(暴力枚举)

    题目链接: abs Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 131072/131072 K (Java/Others) Pro ...

  4. STL容器特征总结与迭代器失效

    Vector 内部数据结构:连续存储,例如数组. 随机访问每个元素,所需要的时间为常量. 在末尾增加或删除元素所需时间与元素数目无关,在中间或开头增加或删除元素所需时间随元素数目呈线性变化. 可动态增 ...

  5. storm相关技术

    There are two kinds of nodes on a Storm cluster: the master node and the worker nodes. 有两种节点,主节点和wor ...

  6. About getByClass

    不能获取class为多个的情况 function getByClass(parent,cls){ var res=[]; var ele=parent.getElementsByTagName(&qu ...

  7. 数据结构与算法(5)----->二叉树

    1.  概念 二叉树节点的结构: class Node{ int value; // value表示二叉树的节点值 Node left; Node right; // left和right表示二叉树的 ...

  8. AtCoder Grand Contest 028 A:Two Abbreviations

    题目传送门:https://agc028.contest.atcoder.jp/tasks/agc028_a 题目翻译 给你两个串\(s\)与\(t\),长度分别为\(n,m\).问你存不存在一个串长 ...

  9. 查看MySql数据库物理文件存放位置

    查找数据库文件位置使用命令 show global variables like "%datadir%";

  10. python3 + selenium + eclipse 中报:Unable to find a matching set of capabilities

    在环境python3 + selenium + eclipse 运行报错::Unable to find a matching set of capabilities 解决办法:Update Fire ...