codeforces772C
给一段序列,给你去掉所有数字的顺序,输出每去掉一个数,当前联通的子序列的最大值。
倒着来,每次插入一个数,然后求联通的最大值,线段树每个节点标记一下,区间的左右是否插入了数字,还有如果有数字从左边/右边开始连续子序列的值,还有这个节点的区间是否连续。
#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的更多相关文章
随机推荐
- IE不支持HTML5表单属性placeholder的解决办法
1. [代码][JavaScript]代码 (function ($) { $.fn.placeholder = function (options) { var defaults ...
- ios审核过程十大常见被拒问题
欢迎加入ios马甲包经验交流群,群聊号码:744520623 2018年伊始,苹果并没有因为新年的气氛而对CP们“网开一面”.频繁锁榜.调整排名规则以及关键词覆盖算法……不断抛出的大动作,让CP们叫苦 ...
- BZOJ 1638 [Usaco2007 Mar]Cow Traffic 奶牛交通:记忆化搜索【图中边的经过次数】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1638 题意: 给你一个有向图,n个点,m条有向边. 对于所有从入度为0的点到n的路径,找出 ...
- 分享知识-快乐自己:SpringMVC 底层执行原理解析
底层实现原理图: 观看底层代码: 1):打开 web.xml 文件 2):按住 Ctrl + 鼠标左键 进入底层查看源码 3):按住 Ctrl+o 找到对应的方法doDispatch 5): ...
- java中相对路径加载xml
一.xml文件一般的存放位置有三个: 1.放在WEB-INF下: 2.xml文件放在/WEB-INF/classes目录下或classpath的jar包中: 3.放在与解析它的java类同一个包中,不 ...
- jQuery bootstrap框架下重置下拉框选择
前端页面中下拉选择框采用bootstrap-select美化,如下图:
- Mesos的quorum配置引发的问题
Mesos安装完毕后,发现agent无法和master关联(通过WebUI的agent页面无法看到agent信息),查看日志显示: Elected as the leading master! sta ...
- bzoj 4032 [ HEOI 2015 ] 最短不公共子串 —— 后缀自动机+序列自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4032 序列自动机其实就是每个位置记录一下某字母后面第一个出现位置,为了子序列能尽量长. 对字 ...
- maven学习九 关于maven一些參數
一 maven profile: 不同的运行环境,比如开发环境.测试环境.生产环境,而我们的软件在不同的环境中,有的配置可能会不一样,比如数据源配置.日志文件配置.以及一些软件运行过程中的基 ...
- Docker入门(四):服务(Services)
这个<Docker入门系列>文档,是根据Docker官网(https://docs.docker.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指 ...