http://www.lydsy.com/JudgeOnline/problem.php?id=3938

以时间为x轴,以距离为y轴,那么每个机器人的行走路径就是一条折线

把折线分段加入线段树里,然后就是线段树维护单点一次函数最大值和最小值

调了半下午+一晚上一直在TTT

今早突然发觉,

之前用来贡献最大值的一次函数和最小值的一次函数都放在了一颗线段树里

下传的时候,同时更新最大值和最小值,

导致只需要更新最小值的一次函数的时候也更新了最大值的一次函数

由于永久标记虽然不会出错,但过多的下放标记浪费了时间

改成两颗线段树,马上就A了

我算不算体验到了 昏天黑地调代码一直TTT一觉起来灵机一动就A了的 激动???

要不是在学校机房我就大叫了,哈哈哈哈哈哈哈哈哈哈哈

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm> using namespace std; typedef long long LL; #define N 100001 struct node
{
int t,v;
node(int t=,int v=):t(t),v(v) {}
}e[N*]; int cnt,nxt[N*],ed[N]; int q[N*];
LL pos[N]; int root,tot;
int ROOT,TOT; struct TREE
{
int mxA;
int lc,rc;
LL mxB;
}TR[N*]; struct tree
{
int miA;
int lc,rc;
LL miB;
}tr[N*]; LL ans; template<typename T>
void read(T &x)
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=f;
} void DOWN(int &k,int l,int r,int a,LL b)
{
if(!k) k=++TOT;
int mid=l+r>>;
if(!TR[k].mxA && !TR[k].mxB)
{
TR[k].mxA=a;
TR[k].mxB=b;
}
else if(l==r) TR[k].mxB=max(TR[k].mxB,b);
else
{
LL minow,mipre,mxnow,mxpre;
minow=min(b,1LL*(r-l)*a+b);
mxnow=max(b,1LL*(r-l)*a+b);
mipre=min(TR[k].mxB,1LL*(r-l)*TR[k].mxA+TR[k].mxB);
mxpre=max(TR[k].mxB,1LL*(r-l)*TR[k].mxA+TR[k].mxB);
if(minow>=mxpre)
{
TR[k].mxA=a;
TR[k].mxB=b;
}
else if(mipre>=mxnow);
else if(1LL*a*(mid-l)+b>1LL*TR[k].mxA*(mid-l)+TR[k].mxB)
{
if(TR[k].mxB>b) DOWN(TR[k].lc,l,mid,TR[k].mxA,TR[k].mxB);
else DOWN(TR[k].rc,mid+,r,TR[k].mxA,1LL*(mid+-l)*TR[k].mxA+TR[k].mxB);
TR[k].mxA=a;
TR[k].mxB=b;
}
else
{
if(TR[k].mxB>b) DOWN(TR[k].rc,mid+,r,a,1LL*a*(mid+-l)+b);
else DOWN(TR[k].lc,l,mid,a,b);
}
}
} void down(int &k,int l,int r,int a,LL b)
{
if(!k) k=++tot;
int mid=l+r>>;
if(!tr[k].miA && !tr[k].miB)
{
tr[k].miA=a;
tr[k].miB=b;
}
else if(l==r) tr[k].miB=min(tr[k].miB,b);
else
{
LL minow,mipre,mxnow,mxpre;
minow=min(b,1LL*(r-l)*a+b);
mxnow=max(b,1LL*(r-l)*a+b);
mipre=min(tr[k].miB,1LL*(r-l)*tr[k].miA+tr[k].miB);
mxpre=max(tr[k].miB,1LL*(r-l)*tr[k].miA+tr[k].miB);
if(mxnow<=mipre)
{
tr[k].miA=a;
tr[k].miB=b;
}
else if(mxpre<=minow);
else if(1LL*a*(mid-l)+b>1LL*tr[k].miA*(mid-l)+tr[k].miB)
{
if(tr[k].miB<b) down(tr[k].rc,mid+,r,a,1LL*(mid+-l)*a+b);
else down(tr[k].lc,l,mid,a,b);
}
else
{
if(tr[k].miB<b) down(tr[k].lc,l,mid,tr[k].miA,tr[k].miB);
else down(tr[k].rc,mid+,r,tr[k].miA,1LL*tr[k].miA*(mid+-l)+tr[k].miB);
tr[k].miA=a;
tr[k].miB=b;
}
}
} void CHANGE(int &k,int l,int r,int opl,int opr,int a,LL b)
{
if(!k) k=++TOT;
if(l==opl && r==opr)
{
DOWN(k,l,r,a,b);
return;
}
int mid=l+r>>;
if(opr<=mid) CHANGE(TR[k].lc,l,mid,opl,opr,a,b);
else if(opl>mid) CHANGE(TR[k].rc,mid+,r,opl,opr,a,b);
else
{
CHANGE(TR[k].lc,l,mid,opl,mid,a,b);
CHANGE(TR[k].rc,mid+,r,mid+,opr,a,1LL*(mid+-opl)*a+b);
}
} void change(int &k,int l,int r,int opl,int opr,int a,LL b)
{
if(!k) k=++tot;
if(l==opl && r==opr)
{
down(k,l,r,a,b);
return;
}
int mid=l+r>>;
if(opr<=mid) change(tr[k].lc,l,mid,opl,opr,a,b);
else if(opl>mid) change(tr[k].rc,mid+,r,opl,opr,a,b);
else
{
change(tr[k].lc,l,mid,opl,mid,a,b);
change(tr[k].rc,mid+,r,mid+,opr,a,1LL*(mid+-opl)*a+b);
}
} void QUERY(int k,int l,int r,int pos)
{
if(!k) return;
if(l==r)
{
ans=max(ans,TR[k].mxB);
return;
}
ans=max(ans,1LL*(pos-l)*TR[k].mxA+TR[k].mxB);
int mid=l+r>>;
if(pos<=mid) QUERY(TR[k].lc,l,mid,pos);
else QUERY(TR[k].rc,mid+,r,pos);
} void query(int k,int l,int r,int pos)
{
if(!k) return;
if(l==r)
{
ans=max(ans,-tr[k].miB);
return;
}
ans=max(ans,-(1LL*(pos-l)*tr[k].miA+tr[k].miB));
int mid=l+r>>;
if(pos<=mid) query(tr[k].lc,l,mid,pos);
else query(tr[k].rc,mid+,r,pos);
} int main()
{
//freopen("data.in","r",stdin);
//freopen("my.out","w",stdout);
int n,m,k,x,t;
char s[];
read(n); read(m);
for(int i=;i<=n;++i)
{
read(pos[i]);
ed[i]=i;
e[i].t=;
e[i].v=;
}
cnt=n;
int sum=;
int last;
while(m--)
{
read(t);
scanf("%s",s);
if(s[]=='q') q[++sum]=t;
else
{
read(k); read(x);
e[++cnt].v=x; e[cnt].t=t;
nxt[ed[k]]=cnt;
ed[k]=cnt;
}
last=t;
}
for(int i=;i<=n;++i)
{
e[++cnt].t=last;
e[cnt].v=;
nxt[ed[i]]=cnt;
ed[i]=cnt;
}
int siz;
for(int i=;i<=n;++i)
{
int j;
for(j=i;j!=ed[i];j=nxt[j])
{
CHANGE(ROOT,,last,e[j].t,e[nxt[j]].t,e[j].v,pos[i]);
change(root,,last,e[j].t,e[nxt[j]].t,e[j].v,pos[i]);
pos[i]+=1LL*(e[nxt[j]].t-e[j].t)*e[j].v;
}
}
for(int i=;i<=sum;++i)
{
ans=;
QUERY(ROOT,,last,q[i]);
query(root,,last,q[i]);
printf("%lld\n",ans);
}
}

bzoj千题计划220:bzoj3938: Robot的更多相关文章

  1. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  2. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  3. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  4. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

  5. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

  6. bzoj千题计划304:bzoj3676: [Apio2014]回文串(回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3676 回文自动机模板题 4年前的APIO如今竟沦为模板,,,╮(╯▽╰)╭,唉 #include& ...

  7. bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹

    http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...

  8. bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机

    http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...

  9. bzoj千题计划250:bzoj3670: [Noi2014]动物园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3670 法一:KMP+st表 抽离nxt数组,构成一棵树 若nxt[i]=j,则i作为j的子节点 那么 ...

随机推荐

  1. 一些比较隐秘的OJ的网址

    ( 1 )COGS:cogs.pro:8080 ( 2 )AGC:agc012.contest.atcoder.jp ( 3 )CS Acaemy:csacademy.com ( 4 )JoyOI:w ...

  2. ajax 上传文件

    最近做公司官网,需要用到上传文件功能,由于是用JQ写的,用到了input标签 的type=file 属性,然后利用表单提交方式上传,代码如下: $('#upload_video').change(fu ...

  3. 云计算之路-阿里云上:博客web服务器轮番CPU 100%

    今天下午14:30左右开始,不知道怎么回事,博客站点负载均衡中的web服务器轮番CPU 100%.平时访问高峰5台服务器就能稳稳支撑,而今天发现CPU出现100%问题后就开始加服务器,结果到目前加到了 ...

  4. 2018 年 3 月 iOS架构师 面试总结

    序言: 今年2月中下旬因为个人原因,换了一份工作,3月初期间面试了有3,4家,基本都是D轮或者刚刚上市的公司,也有上榜的BAT,也从他们的面试笔试中看到了自己的一些不足,于是就想写出来和大家分享一下, ...

  5. Python多线程爬虫与多种数据存储方式实现(Python爬虫实战2)

    1. 多进程爬虫 对于数据量较大的爬虫,对数据的处理要求较高时,可以采用python多进程或多线程的机制完成,多进程是指分配多个CPU处理程序,同一时刻只有一个CPU在工作,多线程是指进程内部有多个类 ...

  6. Hive数据仓库笔记(一)

    Hive建表: CREATE TABLE records (year STRING,temperature INT, quality INT) ROW FORMAT DELIMITED FIELDS ...

  7. C# 值类型与引用类型的异同

    int,bool,decimal等为值类型 List,Stream等为引用类型 用等号设置一个值类型变量等于另一个变量时,会完成复制,之后这两个变量相互之间没有任何影响: 对引用使用等号时,这两个引用 ...

  8. 设计模式——装饰器模式(C++实现)

    #include <iostream> #include <string> using namespace std; class Component { public: ; } ...

  9. NGUI_Depth

    四.深度(Depth)概念; 1. (1).每一个UIPanel和每一个UI控件都一定会有一个Depth,深度值大代表显示的优先级高(会趋向于在界面更上层显示) (2).Depth决定的是UI的显示层 ...

  10. 二分partition算法应用

    一个二分partition算法,将整个数组分解为小于某个数和大于某个数的两个部分,然后递归进行排序算法. 法一: int partition(vector<int>&arr, in ...