1 条题解
-
0
自动搬运
来自洛谷,原作者为

hsfzLZH1
我永远喜欢珂朵莉搬运于
2025-08-24 22:11:56,当前版本为作者最后更新于2019-09-12 16:46:20,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
出题人: hsfzLZH1
本题主要考察模型转化和线段树。
题目大意
次操作,每次操作为以下两种之一:
-
add a v l r,告诉你有一个篮球,在时间段 时在空中,时刻 时的高度为 ,初始向上速度为 。篮球的高度 随在空中的时长 的变化为 。 -
query x,询问在时刻 ,所有已知的在空中的篮球中,最高的一个的高度是多少。 如果此时不存在在空中的篮球,输出Undefined。
30pts
记录已知的所有篮球的 ,对一个时刻进行查询时,判断每个球是否在空中,如果是,计算这个球此时的高度,并取最大值即可。时间复杂度 。
60pts
将时间轴当做横坐标,篮球的高度当做纵坐标。
篮球的高度 与时刻 的关系式:
每次询问,给定 ,而 的取值会随着线段的不同而不同,此时 为定值。对每个篮球,令 ,你需要求出满足 时最大的 。
由此,问题转化为两种操作:
-
在平面上插入一条线段。
-
求所有与 相交的线段中交点 坐标最大的一个。
这就是 李超线段树 的模板题了。由于题目中有小数,可以将所有时间乘以 后转化为整数。令 ,时间复杂度 ,空间复杂度 。
100pts
注意到 的值可能很大,此时可以用 询问离线+离散化 或 动态开点 的方法减小 的值。
参考代码
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define double long double using namespace std; const int maxn=100010; const int inf=1e9+1; const int ddd=20000010; const double g=9.8; int m,cur; char op[10]; double a,v,x,l,r; struct seg { double a,b; double f(double x){return x*a+b;} }s[maxn]; int rt,cnt,lc[ddd],rc[ddd],id[ddd]; void update(int&o,int l,int r,int ql,int qr,int v) { if(r<ql||l>qr)return; if(!o)o=++cnt; if(ql<=l&&r<=qr) { if(!id[o])id[o]=v; else { if(s[v].f(l/1000.0)>=s[id[o]].f(l/1000.0)&&s[v].f(r/1000.0)>=s[id[o]].f(r/1000.0)){id[o]=v;return;} if(s[v].f(l/1000.0)<=s[id[o]].f(l/1000.0)&&s[v].f(r/1000.0)<=s[id[o]].f(r/1000.0))return; if(l==r)return; int mid=(l+r)>>1; if(s[v].f(l/1000.0)>=s[id[o]].f(l/1000.0)) { if(s[v].f(mid/1000.0)>=s[id[o]].f(mid/1000.0))update(rc[o],mid+1,r,ql,qr,id[o]),id[o]=v; else update(lc[o],l,mid,ql,qr,v); } else { if(s[v].f(mid/1000.0)<=s[id[o]].f(mid/1000.0))update(rc[o],mid+1,r,ql,qr,v); else update(lc[o],l,mid,ql,qr,id[o]),id[o]=v; } } return; } int mid=(l+r)>>1; update(lc[o],l,mid,ql,qr,v); update(rc[o],mid+1,r,ql,qr,v); } int query(int o,int l,int r,int x) { if(!o)return 0; if(l==r)return id[o]; int mid=(l+r)>>1,ans; if(x<=mid)ans=query(lc[o],l,mid,x); else ans=query(rc[o],mid+1,r,x); if(!id[o])return ans; if(!ans)return id[o]; if(s[id[o]].f(x/1000.0)>=s[ans].f(x/1000.0))return id[o]; return ans; } main() { scanf("%d",&m); while(m--) { scanf("%s",op); if(op[0]=='a') { cur++; scanf("%Lf%Lf%Lf%Lf",&a,&v,&l,&r); s[cur].a=v+g*l;s[cur].b=a-g/2*l*l-v*l; update(rt,-inf,inf,(int)(l*1000.0),(int)(r*1000.0),cur); } else { scanf("%Lf",&x); int t=query(rt,-inf,inf,(int)(x*1000.0)); if(!t)printf("Undefined\n"); else printf("%Lf\n",-g/2*x*x+s[t].a*x+s[t].b); } } return 0; } -
- 1
信息
- ID
- 4487
- 时间
- 1000ms
- 内存
- 500MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者