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);
}
}

最新文章

  1. apache2.4域名配置参数
  2. java窗口添加背景
  3. [python] 视频008
  4. Android应用开发基础篇(3)-----ListView
  5. java方法笔记
  6. iOS不可变数组的所有操作
  7. 推荐一款基于bootstrap的漂亮的前端模板—inspinia_admin
  8. [Spark性能调优] 第一章:性能调优的本质、Spark资源使用原理和调优要点分析
  9. Angular(01)-- 架构概览
  10. CSS3中很容易混淆的transform,translate,transition。如何去区分,以及综合写法。
  11. zookeeper的Java端API应用
  12. 【IDE】我的花里胡哨VS
  13. java 字符串的运算公式直接转计算结果
  14. Ex 6_5棋子放置问题_第八次作业
  15. 隐藏网页中DIV和DOM的各种方法
  16. [Java] I/O底层原理之二:网络IO及网络编程
  17. freepbx的SIP通话客户端X-lite Yate eyeBeam Linphone
  18. 使用nginx-vod-module hls &amp;&amp;dash &amp;&amp;Thumbnail 处理
  19. 洛谷 P1967 货车运输(克鲁斯卡尔重构树)
  20. PHP利用pcntl_exec突破disable_functions

热门文章

  1. wpf 研究之道 winform or wpf,u choose who?
  2. struts_自定义日期类型转换器
  3. Genymotion模拟器的安装及常见问题解决方法
  4. 兄弟连PHP培训教你提升效率的20个要点
  5. 基于Ubuntu的LNMP环境搭建
  6. 浅析Python3中的bytes和str类型
  7. 每天学点mysql
  8. centos-6.7 内核升级(转)
  9. Android权限Uri.parse的几种用法(转载)
  10. Android中文API (109) —— SimpleCursorTreeAdapter