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

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

 #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. 基于node.js及express实现中间件,实现post、get

    首先,当然是有必要的环境,安装node,这个我就不多说了. 依赖模块: "express": "^4.13.4", "request": & ...

  2. inode、软连接、硬链接

    一.inode是什么? 理解inode,要从文件储存说起.文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector).每个扇区储存512字节(相当于0.5KB).操作系统读取 ...

  3. hdu-5862 Counting Intersections(线段树+扫描线)

    题目链接: Counting Intersections Time Limit: 12000/6000 MS (Java/Others)     Memory Limit: 65536/65536 K ...

  4. Mac使用记录

    ---恢复内容开始--- brew list //查看brew安装东东 ls //当前目录下内容 brew --cache //查看brew下载目录 /usr/local/Cellar/ //隐藏文件 ...

  5. 百度地图API的第一次接触——右键菜单

    1.初始化地图 var map = new BMap.Map("container"); var point = new BMap.Point(116.404, 39.915); ...

  6. 2012年浙大:Sharing

    题目描述: To store English words, one method is to use linked lists and store a word letter by letter. T ...

  7. webAPP meta 标签大全

    1.先说说mate标签里的viewport: viewport即可视区域,对于桌面浏览器而言,viewport指的就是除去所有工具栏.状态栏.滚动条等等之后用于看网页的区域.对于传统WEB页面来说,9 ...

  8. BOM——浏览器对象模型(Browser Object Model)

    什么是BOM? BOM是Browser Object Model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对 ...

  9. Tomcat的安装及使用

    下面是我搭建Tomcat的过程,记录一下 下载地址:http://tomcat.apache.org/  我下载的是8.5.30版本 安装 下载完成后解压到D盘 (配置变量的的教程网上大把随便搜) 1 ...

  10. 连接带密码的access数据库

    在网上找了很多都不靠谱,稀里哗啦的弄一堆连接字符串,很不优雅. 这个方法很简单: 1.在“连接”这页中,下方有“输入登录数据库的信息”用户名:admin,并在下面选择“空白密码” 2.在“所有”这页的 ...