[CSP-S模拟测试]:老司机的狂欢(LIS+LCA)
题目背景
光阴荏苒。
不过,两个人还在,两支车队还在,熟悉的道路、熟悉的风景,也都还在。
只是,这一次,没有了你死我活的博弈,似乎和谐了许多。
然而在机房是不允许游戏的,所以班长$XZY$对游戏界面进行了降维打击,结果。。。
题目传送门(内部题71)
输入格式
第一行两个正整数$n,k$;
接下来$n$行,第$i$行两个整数$x_i,a_i$。
输出格式
第一行一个非负整数$t$,表示狂欢最多能持续的时间($t=0$是合法的)。
如果有老司机有意见,第二行输出$-1$;
否则接下来$k$行每行$1$个正整数,表示字典序最小的方案。
对于每个测试点,如果第一行正确,计$5$分;在此前提下,如果全部正确,再计$5$分。
样例
样例输入:
4 3
-69 2
75 -2
-85 1
96 -1
样例输出:
10
1
3
4
数据范围与提示
样例解释:
共有两种方案使得狂欢时间为最长的$10$秒:$\{1,3,4\}$和$\{2,3,4\}$。显然前者字典序更小。
数据范围:
对于$20\%$的数据,$n\leqslant 15$;
对于$40\%$的数据,$n\leqslant 1,000$;
对于另$10\%$的数据,$k=1$;
对于另$10\%$的数据,$k=n$;
对于$100\%$的数据,$k\leqslant n\leqslant 10^5,|x_i|\leqslant 10^{18},|a_i|\leqslant 10^8$。
数据保证$x_i$两两不同。
题解
看到$x_i$两两不同,先排个序。
再来考虑第一问,可以用二分答案,考虑如何$judge$,其实就是用公式$s=\frac{1}{2}at^2$算出来现在的位置,然后用树状数组计算$LIS$即可。
再来考虑第二问。
先考虑$-1$的情况,其实就是最优时间内的$LIS$比$k$大。
再来考虑一般情况,我们可以将求$LIS$的过程看成是一棵树,每个点的父亲是向它转移的最优的点,深度最大的点到根节点的链就是答案。
但是需要注意的是我们排了序,所以为了保证最小,我们在比较字典序大小的时候应该比较两个点到其$LCA$中点的编号的最小值,因为再往上都是一样的,不用考虑。
时间复杂度:$\Theta(n\log n\log t+n\log^2 n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec{long long x,a;int id;}e[100001];
int n,k;
int eftr[100001],now;
long long p[100001],t[100001];
int fa[100001][21],minn[100001][21];
int ans[100001];
pair<int,int> tr[100001];
bool cmp(rec a,rec b){return a.x<b.x;}
int lowbit(int x){return x&-x;}
bool getmin(pair<int,int> a,pair<int,int> b)
{
if(a.first!=b.first)return a.first<b.first;
int minx=a.second,miny=b.second,x=a.second,y=b.second;
for(int i=19;i>=0;i--)
if(fa[x][i]!=fa[y][i])
{
minx=min(minx,minn[x][i]);
miny=min(miny,minn[y][i]);
x=fa[x][i];y=fa[y][i];
}
return minx>miny;
}
void efadd(int x,int w){for(int i=x;i<=n;i+=lowbit(i))eftr[i]=max(eftr[i],w);}
int efask(int x){int res=0;for(int i=x;i;i-=lowbit(i))res=max(res,eftr[i]);return res;}
void add(int x,pair<int,int> w){for(int i=x;i<=n;i+=lowbit(i))if(getmin(tr[i],w))tr[i]=w;}
pair<int,int> ask(int x){pair<int,int> res=make_pair(0,0);for(int i=x;i;i-=lowbit(i))if(getmin(res,tr[i]))res=tr[i];return res;}
bool judge(int x)
{
memset(eftr,0,sizeof(eftr));
for(int i=1;i<=n;i++)t[i]=p[i]=2*e[i].x+e[i].a*x*x;
sort(t+1,t+n+1);
for(int i=1;i<=n;i++)
{
p[i]=lower_bound(t+1,t+n+1,p[i])-t;
efadd(p[i],efask(p[i]-1)+1);
}
now=efask(n);
return now>=k;
}
void build(int x,int father)
{
fa[x][0]=minn[x][0]=father;
for(int i=1;i<=19;i++)
{
fa[x][i]=fa[fa[x][i-1]][i-1];
minn[x][i]=min(minn[x][i-1],minn[fa[x][i-1]][i-1]);
}
}
int main()
{
memset(minn,0x3f,sizeof(minn));
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&e[i].x,&e[i].a);
e[i].id=i;
}
sort(e+1,e+n+1,cmp);
int lft=1,rht=86400,res=1;
while(lft<=rht)
{
int mid=(lft+rht)>>1;
if(judge(mid)){lft=mid+1;res=mid;}
else rht=mid-1;
}
judge(res);
printf("%d\n",res);
if(now>k){puts("-1");return 0;}
for(int i=1;i<=n;i++)t[i]=p[i]=2*e[i].x+e[i].a*res*res;
sort(t+1,t+n+1);
for(int i=1;i<=n;i++)
{
p[i]=lower_bound(t+1,t+n+1,p[i])-t;
pair<int,int> flag=ask(p[i]-1);
build(e[i].id,flag.second);
add(p[i],make_pair(flag.first+1,e[i].id));
}
int now=ask(n).second;
for(int i=1;i<=k;i++)
{
ans[i]=now;
now=fa[now][0];
}
sort(ans+1,ans+k+1);
for(int i=1;i<=k;i++)printf("%d\n",ans[i]);
return 0;
}
rp++
[CSP-S模拟测试]:老司机的狂欢(LIS+LCA)的更多相关文章
- NOIP 模拟 $18\; \rm 老司机的狂欢$
题解 \(by\;zj\varphi\) 一道很有趣的题,我用的动态开点线段树和倍增 首先对于第一问,不难想到要二分,二分时间,因为时间长一定不会比时间短能跑的人多 那么如何 check,先将所有老司 ...
- HZOJ 老司机的狂欢
比较神仙的一道题. 第一问还比较简单一点: t是否可行是单调的,考虑二分. 考虑对于两个人i,j合法的条件,设x(i)<x(j),那么$x(i)+\frac {a(i)*t^2}{2} < ...
- 测试老司机都在用的表白神器你会吗?-Fiddler之AutoResponse线上调试
一.Fiddler在线调试功能和表白神器介绍 在以往的工作中,线上有bug,就需要把文件弄到本地来改,但经常会碰见本地环境又和线上不一样,导致调试困难,闭着眼睛改好之后传到线上去看对不对,不对的话 ...
- [CSP-S模拟测试]:影子(并查集+LCA)
题目描述 一个人有很多的影子,新的旧的,他们不断消失重来.学者的影子在他苍白色的精神图景里成为了$n$个黑色的点,他们伸长的触手交叉形成了一颗黑色的树.假使每个影子点拥有一个权值$d_i$,黑色的树边 ...
- [考试反思]1015csp-s模拟测试75:混乱
赶上一套极其傻逼的题(是傻逼,不是简单) T1超级卡精 T2模拟(输出卡"0.0"与"-0.0"不开spj),而且数据诡异乱打就能A(貌似给这道题的时间越长分越 ...
- 老司机带你用vagrant打造一站式python开发测试环境
前言 作为一个学习和使用Python的老司机,好像应该经常总结一点东西的,让新司机尽快上路,少走弯路,然后大家一起愉快的玩耍. 今天,咱们就使用vagrant配合xshell打造一站式Python ...
- 老司机的奇怪noip模拟T2-huangyueying
2. 黄月英(huangyueying.cpp/c/pas )[问题描述]xpp 每天研究天文学研究哲学,对于人生又有一些我们完全无法理解的思考.在某天无聊学术之后, xpp 打开了 http://w ...
- javbus爬虫-老司机你值得拥有
# 起因 有个朋友叫我帮忙写个爬虫,爬取javbus5上面所有的详情页链接,也就是所有的https://www.javbus5.com/SRS-055这种链接, 我一看,嘿呀,这是司机的活儿啊,我绝对 ...
- zz“老司机”成长之路:自动驾驶车辆调试实践
随着自动驾驶技术的发展,一辆新车从被改装到上路需要经过的调试流程也有了许多提升.今天,我希望结合自己之前的调车经验来跟大家分享一下我们是如何将系统的各个模块逐步上车.调试.集成,进而将一辆“新手”车培 ...
随机推荐
- 关于Java多线程的一些面试问题
1.ArrayList和Vecoter区别? Array和ArrayList的异同点一.Array和ArrayList的区别#1. Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大 ...
- KMP字符串匹配 模板 洛谷 P3375
KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...
- 使用git命令删除branch
使用git删除server上的一个branch注意事项: 1. 使用命令:git push origin –delete 分支名 (分支名称需要去掉origin,如果有), git branch ...
- Linux/Unix下pid文件作用浅析
转载:http://blog.csdn.net/changli_90/article/details/8911191 在Linux系统的目录/var/run下面一般我们都会看到很多的*.pid文件.而 ...
- [LeetCode] 210. 课程表 II
题目链接:https://leetcode-cn.com/problems/course-schedule-ii/ 题目描述: 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前 ...
- UESTC-1057 秋实大哥与花(线段树+成段加减+区间求和)
秋实大哥与花 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit St ...
- JVM — 性能调优
概念: 一:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的.” ...
- IBM公司的面试题,看看你能做出多少。
进入IBM差不多是每一个IT人的梦想.IBM公司向来以高素质人才作为企业持续竞争力的保证,所以经常出一些千奇百怪的面试题,来考验一个人的综合能力,以下是5道IBM曾经出过的面试题,看看你能作出几道: ...
- ECMAScrip5 二
一.ES5的严格模式 在严格模式下,声明变量必须使用 var 在严格模式下,不能使用八进制 在严格模式下,不能使用arguments.callee 在严格模式下,不能使用eval() //eva ...
- python之路之——操作系统的发展历史
阅读目录 手工操作 —— 穿孔卡片 批处理 —— 磁带存储和批处理系统 多道程序系统 分时系统 实时系统 通用操作系统 操作系统的进一步发展 操作系统的作用 手工操作 —— 穿孔卡片 1946年第一台 ...