博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【bzoj3938】 Robot
阅读量:5077 次
发布时间:2019-06-12

本文共 2622 字,大约阅读时间需要 8 分钟。

 (题目链接)

题意

  给出数轴上$n$个点,有$m$个操作,在时间$t$让一个点以一定的速度移动,或者询问时间$t$时距离原点最远的点。

Solution

  超哥线段树。时间当做横坐标,负半轴的情况斜率和截距乘上$-1$再做一遍。

  话说我为什么要离散化=  =

细节

  LL

代码

// bzoj3938#include
#include
#include
#include
#include
#include
#define LL long long#define inf (1ll<<60)#define eps 1e-8#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)using namespace std;const int maxn=1000010;LL ans[maxn],a[maxn];int n,m,cnt,tot,last[maxn],tim[maxn],q[maxn];char ch[100];struct seg { LL k,b,l,r; LL ch(LL x) {return k*x+b;}}v[maxn];struct node {int cov;seg mx;}tr[maxn<<2];double X(seg a,seg b) { return a.k==b.k ? inf : 1.0*(a.b-b.b)/(b.k-a.k);}void insert(int k,int l,int r,int s,int t,seg g) { int mid=(l+r)>>1; if (l==s && r==t) { if (!tr[k].cov) tr[k].mx=g,tr[k].cov=1; else { seg a1=tr[k].mx,a2=g;double x=X(a1,a2); if (a1.ch(tim[l])
=tim[r]) {tr[k].mx=a1;return;} if (x<=tim[mid]) tr[k].mx=a2,insert(k<<1,l,mid,s,mid,a1); else tr[k].mx=a1,insert(k<<1|1,mid+1,r,mid+1,t,a2); } return; } if (t<=mid) insert(k<<1,l,mid,s,t,g); else if (s>mid) insert(k<<1|1,mid+1,r,s,t,g); else insert(k<<1,l,mid,s,mid,g),insert(k<<1|1,mid+1,r,mid+1,t,g);}LL query(int k,int l,int r,int x) { if (l==r) return tr[k].cov ? tr[k].mx.ch(x) : 0; int mid=(l+r)>>1;LL t=0; if (x<=tim[mid]) t=query(k<<1,l,mid,x); else t=query(k<<1|1,mid+1,r,x); return tr[k].cov ? max(t,tr[k].mx.ch(x)) : t;}void clear(int k,int l,int r) { tr[k].cov=0; if (l==r) return; int mid=(l+r)>>1; clear(k<<1,l,mid); clear(k<<1|1,mid+1,r);}int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%lld",&a[i]); for (int i=1;i<=n;i++) v[++cnt]=(seg){0,a[i],0,-1},last[i]=cnt; for (int x,i=1;i<=m;i++) { scanf("%d",&tim[i]); scanf("%s",ch); if (ch[0]=='c') { scanf("%d%lld",&x,&v[++cnt].k); v[last[x]].r=v[cnt].l=tim[i];v[cnt].r=-1; a[x]=v[last[x]].k*tim[i]+v[last[x]].b; v[cnt].b=a[x]-v[cnt].k*tim[i]; last[x]=cnt; } if (ch[0]=='q') q[++tot]=tim[i]; } m=unique(tim,tim+1+m)-tim-1; for (int i=1;i<=cnt;i++) { if (v[i].r==-1) v[i].r=tim[m]; int l=lower_bound(tim,tim+1+m,v[i].l)-tim; int r=lower_bound(tim,tim+1+m,v[i].r)-tim; insert(1,0,m,l,r,v[i]); } for (int i=1;i<=tot;i++) ans[i]=query(1,0,m,q[i]); clear(1,0,m); for (int i=1;i<=cnt;i++) { int l=lower_bound(tim,tim+1+m,v[i].l)-tim; int r=lower_bound(tim,tim+1+m,v[i].r)-tim; v[i].k*=-1;v[i].b*=-1; insert(1,0,m,l,r,v[i]); } for (int i=1;i<=tot;i++) ans[i]=max(ans[i],query(1,0,m,q[i])); for (int i=1;i<=tot;i++) printf("%lld\n",ans[i]); return 0;}

 

转载于:https://www.cnblogs.com/MashiroSky/p/6650108.html

你可能感兴趣的文章
数据库一些小知识
查看>>
角色扮演
查看>>
springmvc基础学习2---简单配置文件
查看>>
javascript是做什么的
查看>>
探究QA职能
查看>>
图片加载框架之Glide和Picasso
查看>>
wtforms Form实例化流程(源码解析)
查看>>
[查询]计算机信息系统集成项目经理资质名单网址
查看>>
Android开发之AlarmManager具体解释
查看>>
3.14 下午
查看>>
Delphi COM编程介绍
查看>>
apc
查看>>
.net 新闻点击量修改,避免恶意刷新
查看>>
java集合的并集、交集、差集
查看>>
bzoj 3551
查看>>
[LeetCode] Heaters 加热器
查看>>
学习Python第一天
查看>>
使用一个黑客的小伎俩来实现discuz!邀请功能刷分
查看>>
codeforces 591B Rebranding (模拟)
查看>>
.NET 操作PDF文档以及PDF文件打印摸索总结
查看>>