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

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

 #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. LightOJ 1132 Summing up Powers:矩阵快速幂 + 二项式定理

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1132 题意: 给定n.k,求(1K + 2K + 3K + ... + NK) % 2 ...

  2. php设置文件编码

    <?php @header('Content-type: text/html;charset=UTF-8'); ?>

  3. POJ3694(求割边)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7943   Accepted: 2893 Descripti ...

  4. resiprocate使用入门:内网搭建基于repro的sipproxy测试环境

    测试环境 sipproxy:repro + centos 客户端:windows电脑客户端使用X-Lite,手机andriod客户端使用linphone repro配置和启动 log的配置 如果使用默 ...

  5. ceph安装对象网关

    1.概述 安装3个网关节点分别是:controller-03.controller-04和controller-05,使用ceph gw自带的Civetweb提供服务,前端使用nginx作为前端代理. ...

  6. sorted matrix - search & find-k-th

    sorted matrix ( Young Matrix ) search for a given value in the matrix: 1) starting from upper-right ...

  7. <c和指针>学习笔记3之操作符,表达式与指针

    1 操作符 (1)移位操作符 左移<<:值最左边的几位丢弃,右边多出来的几个空位用0补齐 01101101 011(丢弃)01101000(后面三位补0) 右移>>: 算术左移 ...

  8. 关于 Number() parsint() abs() 的区别

    1. parseInt(‘’)      parseInt() 函数可解析一个字符串,并返回一个整数. 如果第一个字符不是数字或者负号,parseInt() 就会返回NaN 2.Number()    ...

  9. Centos7.2 安装配置 Tengine(nginx)

    一.下载tengine wget http://tengine.taobao.org/download/tengine-2.2.2.tar.gz 二.安装tenginx(nginx)的模块依赖库 yu ...

  10. webbrowser 控件实现WinForm与WebForm交互

    WebBrowser 控件可以让你装载Windows Form 应用程序中的 Web 网页和其它采用浏览器的文件.可以使用webbrowser 控件将现有的web框架控制项加入至 Windows Fo ...