• [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\%$的数据,$nleqslant 15$;
    对于$40\%$的数据,$nleqslant 1,000$;
    对于另$10\%$的数据,$k=1$;
    对于另$10\%$的数据,$k=n$;
    对于$100\%$的数据,$kleqslant nleqslant 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(nlog nlog t+nlog^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
    ",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
    ",ans[i]);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    centos7安装node.js
    docker容器互联,实现目录、服务共享
    解决docker容器中Centos7系统的中文乱码
    修改centos7容器的时间和宿主机时间一致
    linux安装中文字体
    制作OpenOffice的Docker镜像并添加中文字体解决乱码问题
    centos容器yum安装JDK环境
    函数装饰器
    nc(NetCat)命令
    Linux源码包安装程序
  • 原文地址:https://www.cnblogs.com/wzc521/p/11687206.html
Copyright © 2020-2023  润新知