原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html

题目传送门 - CodeForces 516C

题意

  在一个环上,有$n$棵树。

  给出每一个树的高度$h_i$以及每一个树距离他顺时针方向后一个树的距离$d_i$。

  有$m$次询问,每次,都会有一段连续区间内的树萎掉。请你找两棵树$x,y$,最大化$2(h_x+h_y)+dist(x,y)$。其中$dist(x,y)$为这两棵树的距离,这个距离不能包含萎掉的树。

  $n,m\leq 10^5$

题解

  闭着眼睛都能想到线段树。

  我们首先闭着眼睛给$d_i$求个前缀和。

  然后开线段树,维护区间$2h_i-d_{i-1}$的最大值以及$2h_i+d_{i-1}$的最大值,以及区间匹配的两个树的最大的$2(h_x+h_y)+dist(x,y)$。

  然后倍长原序列,每次询问就是区间求$max$。

  UPD(发表这篇博文约30分钟后):

  代码重写了哈哈。又短又漂亮。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200005;
const LL INF=1LL<<56;
int n,m;
LL d[N],h[N];
struct Segment{
LL val,v0,v1;
Segment(){}
Segment(LL a,LL b,LL c){
val=a,v0=b,v1=c;
}
}t[N<<2];
LL read(){
LL x=0;
char ch=getchar();
while (!('0'<=ch&&ch<='9'))
ch=getchar();
while ('0'<=ch&&ch<='9')
x=x*10+ch-48,ch=getchar();
return x;
}
Segment merge(Segment ls,Segment rs){
Segment rt;
rt.val=max(max(ls.val,rs.val),ls.v0+rs.v1);
rt.v0=max(ls.v0,rs.v0);
rt.v1=max(ls.v1,rs.v1);
return rt;
}
void build(int rt,int L,int R){
if (L==R){
t[rt].v0=h[L]-d[L-1],t[rt].v1=h[L]+d[L-1],t[rt].val=-INF;
return;
}
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
build(ls,L,mid);
build(rs,mid+1,R);
t[rt]=merge(t[ls],t[rs]);
}
Segment query(int rt,int L,int R,int xL,int xR){
if (L>xR||R<xL||xL>xR)
return Segment(-INF,-INF,-INF);
if (xL<=L&&R<=xR)
return t[rt];
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
return merge(query(ls,L,mid,xL,xR),query(rs,mid+1,R,xL,xR));
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
d[i]=read()+d[i-1];
for (int i=1;i<=n;i++)
h[i]=read()*2;
for (int i=1;i<=n;i++)
d[i+n]=d[i]+d[n],h[i+n]=h[i];
build(1,1,n*2);
for (int i=1,a,b;i<=m;i++){
scanf("%d%d",&a,&b);
if (b>=a)
a+=n;
printf("%I64d\n",query(1,1,n*2,b+1,a-1).val);
}
return 0;
}

  

题解 - 续 (修改前的题解后一半以及代码)

  然而我代码写的很

  首先,区间求$max$的时候因为懒,为了少写一点代码,强行把一个$\log$的算法写成$\log^2$的。

  第二,我线段树维护的前两个信息不是最大值,而是编号……于是自找麻烦。

  第三,我没有倍长……

  (有空重写)

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
int n,m;
LL d[N],h[N],val[N<<2];
int M[2][N<<2];
LL read(){
LL x=0;
char ch=getchar();
while (!('0'<=ch&&ch<='9'))
ch=getchar();
while ('0'<=ch&&ch<='9')
x=x*10+ch-48,ch=getchar();
return x;
}
LL c(int t,int i){
if (i==0)
return -(1LL<<55);
return t==0?(h[i]-d[i-1]):(h[i]+d[i-1]);
}
int pushup(int ls,int rs,int t){
return c(t,ls)>c(t,rs)?ls:rs;
}
void build(int rt,int L,int R){
if (L==R){
M[0][rt]=M[1][rt]=L,val[rt]=-(1LL<<55);
return;
}
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
build(ls,L,mid);
build(rs,mid+1,R);
M[0][rt]=pushup(M[0][ls],M[0][rs],0);
M[1][rt]=pushup(M[1][ls],M[1][rs],1);
val[rt]=max(max(val[ls],val[rs]),c(0,M[0][ls])+c(1,M[1][rs]));
}
int query(int rt,int L,int R,int xL,int xR,int t){
if (L>xR||R<xL||xL>xR)
return 0;
if (xL<=L&&R<=xR)
return M[t][rt];
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
return pushup(query(ls,L,mid,xL,xR,t),query(rs,mid+1,R,xL,xR,t),t);
}
LL query(int rt,int L,int R,int xL,int xR){
if (L>xR||R<xL||xL>xR)
return 0;
if (xL<=L&&R<=xR)
return val[rt];
int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
return max(max(query(ls,L,mid,xL,xR),query(rs,mid+1,R,xL,xR)),c(0,query(ls,L,mid,xL,xR,0))+c(1,query(rs,mid+1,R,xL,xR,1)));
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
d[i]=read()+d[i-1];
for (int i=1;i<=n;i++)
h[i]=read()*2;
build(1,1,n);
for (int i=1,a,b;i<=m;i++){
scanf("%d%d",&a,&b);
if (b<a){
printf("%I64d\n",query(1,1,n,b+1,a-1));
}
else {
LL ans=max(query(1,1,n,1,a-1),query(1,1,n,b+1,n));
ans=max(ans,c(1,query(1,1,n,1,a-1,1))+d[n]+c(0,query(1,1,n,b+1,n,0)));
printf("%I64d\n",ans);
}
}
return 0;
}

  

CodeForces 516C Drazil and Park 线段树的更多相关文章

  1. Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树

    C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...

  2. codeforces 516c// Drazil and Park// Codeforces Round #292(Div. 1)

    题意:一个圆环上有树,猴子上下其中一棵树,再沿着换跑,再上下另一棵树.给出一个区间,问最大的运动距离是. 给出区间大小dst,和数高数组arr. 设区间[x,y],a[x]=2*arr[x]+dst[ ...

  3. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  4. codeforces 22E XOR on Segment 线段树

    题目链接: http://codeforces.com/problemset/problem/242/E E. XOR on Segment time limit per test 4 seconds ...

  5. Codeforces 588E. A Simple Task (线段树+计数排序思想)

    题目链接:http://codeforces.com/contest/558/problem/E 题意:有一串字符串,有两个操作:1操作是将l到r的字符串升序排序,0操作是降序排序. 题解:建立26棵 ...

  6. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  7. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  8. Codeforces 444C DZY Loves Colors(线段树)

    题目大意:Codeforces 444C DZY Loves Colors 题目大意:两种操作,1是改动区间上l到r上面德值为x,2是询问l到r区间总的改动值. 解题思路:线段树模板题. #inclu ...

  9. Codeforces 85D Sum of Medians(线段树)

    题目链接:Codeforces 85D - Sum of Medians 题目大意:N个操作,add x:向集合中加入x:del x:删除集合中的x:sum:将集合排序后,将集合中全部下标i % 5 ...

随机推荐

  1. python学习第41天

    # 索引 # 认识mysql中的key # index key 普通索引,能够加速查询,辅助索引 # unique key 唯一 + 索引,辅助索引 # primary key 唯一 + 非空 + 聚 ...

  2. 【原创】Linux基础之命令行浏览器links

    有时服务器环境受限,比如在内网环境不能暴露端口从外网访问,用curl看html代码比较累,这时可以使用命令行浏览器来查看相关页面 links 官方:http://links.twibright.com ...

  3. 【原创】数据库基础之Mysql(3)mysql删除历史binlog

    mysql开启binlog后会在/var/lib/mysql下创建binlog文件,如果手工删除,则下次mysql启动会报错: mysqld: File './master-bin.000001' n ...

  4. [Linux][HTTP] Cookie和Set-Cookie

    HTTP 请求报文通过Cookie字段通知服务端当前页面的域生效中的cookie; GET /my/login.php HTTP/1.1 Host: 192.168.88.207:91 Connect ...

  5. C# Winform控件对透明图片重叠时导致图片不透明的解决方法(转)

    在Winform中如果将一个透明图片放在窗体上能正常显示透明,但是如果将该图片放在另一个控件上会导致不能显示透明效果. 解决这种情况,可以采取在控件上使用GDI+绘画出透明图片. 这里我们就以一个pi ...

  6. 锤子科技"临死前"被"接盘" ,内部人士爆料已改签今日头条母公司

    就在昨天,据据锤子科技内部人士透露,部分锤子科技员工在昨天已经接到了相关的临时通知,要求改签劳动合同至今日头条的母公司——字节跳动.至于这是锤子科技真正再度复活还是借尸还魂都不重要,重要的是,作为忠实 ...

  7. Confluence 6 附件存储选项

    在早期的 Confluence 版本中,我们允许存储附件到 WebDav 或者 Confluence 数据库中.针对新的 Confluence 安装,我们不再支持这 2 种存储了. 本地文件系统 在默 ...

  8. error: js/dist/app.js from UglifyJs Unexpected token: name (Dom7)

    What you did I have installed Swiper as normal dependency in my Project and import it to my scripts ...

  9. NIO(五)

    分散读取,聚集写入 package com.cppdy.nio; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import ...

  10. BrupSuite渗透测试笔记(十一)

    一.数据查找和拓展功能的使用 1.BrupSuite高级功能在界面布局上主要分成两个部分,一是菜单栏,另一个是Engagement tools,Brup菜单下包含的数据查找Search 组件状态存储. ...