首页 > 其他分享 >P4098 [HEOI2013] ALO

P4098 [HEOI2013] ALO

时间:2024-01-30 12:22:56浏览次数:24  
标签:ALO le sta 宝石 top tr HEOI2013 P4098 ll

[HEOI2013] ALO

题目描述

Welcome to ALO (Arithmetic and Logistic Online)。这是一个 VR MMORPG,如名字所见,到处充满了数学的谜题。

现在你拥有 \(n\) 颗宝石,第 \(i\) 颗宝石有一个能量密度,记为 \(a_i\),这些宝石的能量密度两两不同。现在你可以选取连续的一些宝石(必须多于一个)进行融合,设他们的能量密度为 \(a_i,a_{i+1},\cdots,a_j\),则融合而成的宝石的能量密度为这些宝石中能量密度的次大值与其他任意一颗宝石的能量密度按位异或的值的最大值。即,假设该段宝石能量密度次大值为 \(k\),则生成的宝石的能量密度为 \(\max\{k\oplus a_p\mid a_p\ne k, i\le p\le j\}\)。

现在你需要知道你怎么选取需要融合的宝石,才能使生成的宝石能量密度最大。

输入格式

第一行,一个整数 \(n\),表示宝石个数。

第二行,\(n\) 个整数,分别表示 \(a_1\) 至 \(a_n\),表示每颗宝石的能量密度,保证对于 \(i\ne j\) 有 \(a_i\ne a_j\)。

输出格式

输出一行一个整数,表示最大能生成的宝石能量密度。

样例 #1

样例输入 #1

5 
9 2 1 4 7

样例输出 #1

14

提示

样例解释

选择区间 \([1,5]\),最大值为 \(7\oplus 9 = 14\)。

数据规模与约定

  • 对于 \(20\%\) 的数据有 \(n\le 100\);
  • 对于 \(50\%\) 的数据有 \(n\le 2000\);
  • 对于 \(100\%\) 的数据有 \(1\le n\le 50000\),\(0\le a_i\le 10^9\)。

2023.4.28:添加两组 hack 数据,不计分。

原题链接

次大值可能感觉不是很好做,但是最大值就还好,因为如果是最大值的话,每一个最大值其实是控制了一个连续的区间的,那么只需要再这个区间上面找到和这个树异或最大的就好了,可持久化trie树的模板题。
那次大值其实也差不多吧,每一个次大值也是控制了一个区间的,我们只用把每个区间找出来,然后在这里面找最大的异或和就好了。

那么怎么找每一个次大值控制的区间范围呢?

如果能够对每个点\(O(logn)\)以下的找到次大值,那就好了。
单调栈好了吧?
能够找到每一个点上一个比它大的点在哪里
嘶,还要找到上两个吧。
没事,对于单调栈来说,很简单。
那么就O(n)的找到了每一个点往前和往后的比它大的前两个点,它的控制范围也在这里面了。就是左右两边到比它大的第二个点为止。
这个区间的找最大异或是可持久化trie的专场,O(1)做了 ?忘记了复杂度多少了
效率应该是很高的。

额,单调栈是错的。。这么简单的东西我都没看出来。。
单调栈找到的不是前两个比它大的,这很明显啊。。然后我写了一个暴力准备对拍,交上去的时候交错了,tm的A了,给我人都整傻了。。
(主要是暴力跑的还飞快
这就是\(O(n^2)\)吗
前面的找次大值的话应该是用二分的,先二分第一个比它大的,再二分第二个比它大的。。
其实简单的可以用双向链表,然后一个一个删除。
上面的是\(O(nlogn)\)下面的是\(O(n)\),我感觉下面的好写一些。
但是双向链表的比较巧妙,也挺好用的,建议学习一下。
这边挂一个暴力的吧(逃

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read() {
	char c=getchar();ll a=0,b=1;
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
ll n,sta[800001],top,a[800001],tr[800001*32][2],last[800001*32],front[800001][3],back[800010][3],tot;
ll root[800001*32];
void insert(ll i,ll x,ll k,ll now)
{
	if(k<0)
	{
		last[x]=now;
		return ;
	}
	ll c=a[now]>>k&1;
	if(i)tr[x][c^1]=tr[i][c^1];
	tr[x][c]=++tot;
	insert(tr[i][c],tr[x][c],k-1,now);
	last[x]=max(last[tr[x][0]],last[tr[x][1]]);
}
ll ask(ll now,ll val,ll k,ll lim)
{
	if(k<0)
	{
		return a[last[now]]^val;
	}
	ll c=val>>k&1;
	if(last[tr[now][c^1]]>=lim)return ask(tr[now][c^1],val,k-1,lim);
	else return ask(tr[now][c],val,k-1,lim);
}
int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n=read();ll Max=0;
	for(ll i=1;i<=n;i++)
	{
		a[i]=read();
		Max=max(Max,a[i]);
	}
	for(int i=1;i<=n;i++)
	{
		int count=0;int j;
		for(j=i-1;j>=1;j--)
		{
			if(a[j]>a[i])front[i][++count]=j;
			if(count==2)break;
		}
	}
	for(int i=1;i<=n;i++)
	{
		int count=0;int j;
		for(j=i+1;j<=n;j++)
		{
			if(a[j]>a[i])back[i][++count]=j;
			if(count==2)break;
		}
	}
//	for(ll i=1;i<=n;i++)失败的单调栈
//	{
//		while(top>0&&a[i]>a[sta[top]])top--;
//		if(top!=0)front[i][1]=sta[top];
//		if(top>1)front[i][2]=sta[top-1];
//		sta[++top]=i;
//	}
//	top=0;
//	for(ll i=n;i>=1;i--)
//	{
//		while(top>0&&a[i]>a[sta[top]])top--;
//		if(top!=0)back[i][1]=sta[top];
//		if(top>1)back[i][2]=sta[top-1];
//		sta[++top]=i;
//	}
	for(ll i=1;i<=n;i++)
	{
		if(back[i][1]==0)back[i][1]=n+1;
		if(back[i][2]==0)back[i][2]=n+1;
	}
	last[0]=-1;
	root[0]=++tot;
	insert(0,root[0],31,0);
	for(ll i=1;i<=n;i++)
	{
		root[i]=++tot;
		insert(root[i-1],root[i],31,i);
	}
	ll ans=0;
	for(ll i=1;i<=n;i++)
	{
		ll st,ed;
		ed=back[i][2]-1;
		st=front[i][2]+1;
		if(Max!=a[i])
			ans=max(ans,ask(root[ed],a[i],31,st));
	}
	cout<<ans<<endl;
	return 0;
}

我来说说这题的我遇到的坑点吧(我为什么这题能调一天吧)
1.开了个k=32,然后没开longlong,结果调了半天,硬是样例过不去。。(01trie树的写法问题)
2.就是上面的说的次大值的问题
3.好像没啥了

这个用链表求次大值的方法是很值得学习的,它是能推广到前面第n个比它大的这种的。
但是有一个要求,就是不能对顺序由要求,就是不要强制在线,但是这个可以预处理,复杂度O(n),所以也没啥。
唉唉,写完这题,对trie树是熟悉了,一天也没了。。。

标签:ALO,le,sta,宝石,top,tr,HEOI2013,P4098,ll
From: https://www.cnblogs.com/HLZZPawa/p/17996840

相关文章

  • [Qt-ColorEditor] Qt颜色编辑器,QColorDialog的优化版,支持RGB和HSV等多种方式选色
    外观分享一下我实现的颜色编辑器,主要原因是Qt的QColorDialog功能较少没法满足需求,目前已经在zeno中使用了,由于zeno有自己的样式表,所以在zeno里长这样:如果不加样式表的话长这样:功能srgb切换颜色轮选色颜色文字选色颜色滑动条选色,RGB和HSV上一个/当前颜色切换,这个主要......
  • SAP dialog 客制化容器选择问题处理
    在使用客制化容器的时候,在里面防止alv展现的时候,layout给了一个zbox,但是有时候不起效,后来找了很久也没解决,就换了一种方式实现,这里就记录一下,顺便展示一下失效的情况我这边就用一下之前的程序来做测试了,程序的构建看这个blog即可https://www.cnblogs.com/pnj-owowa/p/17984569......
  • 计算机服务器中了halo勒索病毒怎么办,halo勒索病毒解密处理流程
    计算机技术的发展与应用为企业的生产生活提供了坚实基础,但同时也为网络安全威胁制造了有利条件。近期,网络上的勒索病毒非常嚣张,给企业的计算机服务器带来严重威胁。近日,云天数据恢复中心接到山东某制造公司的求助,企业的计算机服务器被halo勒索病毒攻击,导致系统所有数据被加密无法使......
  • SAP dialog 自定义搜索帮助 案例+源码
    同之前的blog一样,新建一个9000的屏幕,元素清单配好ok_code即可前置准备准备一个屏幕,具体步骤和之前一样,这边也按步骤做一下状态栏因为这个只是用于搜索帮助的演示,所以不需要应用应用程序工具栏,只需要设置功能键方便返回测试即可标题9000程序PROCESSBEFOREOUTPUT.......
  • SAP dialog使用选择屏幕+容器展现 步骤+源码
    系统自带的选择都是单选的,但是需求不一定是单选的,那么需要和选择屏幕一样的范围选择要怎么做呢,以下是一个样例,通过查询物料号来展现物料表的数据。9000屏幕创建屏幕设置屏幕类型布局编辑构建一个子屏幕subscreen用于防止选择屏幕,构建一个客制化容器contain用于存放......
  • 一起学习Avalonia
    一起学习Avalonia(一)一起学习Avalonia(二)一起学习Avalonia(三)一起学习Avalonia(四)一起学习Avalonia补充(Linux下的使用开发)一起学习Avalonia(五)一起学习Avalonia补充(deepin下的使用开发t调试)一起学习Avalonia(六)一起学习Avalonia(七)一起学习Avalonia(八)一起学习Avalonia(九)一起学习A......
  • Avalonia跨平台入门
    Avalonia跨平台入门第一篇Avalonia跨平台入门第二篇Avalonia跨平台入门第三篇之PopupAvalonia跨平台入门第四篇之Popup在uos下问题Avalonia跨平台入门第五篇之ListBox多选Avalonia跨平台入门第六篇之Grid动态分割Avalonia跨平台入门第七篇之RadioButton的模板Avalonia跨平台入门第......
  • Avalonia TemplatedControl (模板控件)
    在ava中的模板控件相当于wpf中的自定义控件在下面示例中,将绘制一个文本框和一个按钮,用来组合一个搜索控件在app.axaml中加入样式<Application.Styles><FluentTheme/><StyleIncludeSource="/TemplatedControl1.axaml"/></Application.Styles>引入并使用xmlns......
  • Avalonia UserControl
    ava中的用户控件和wpf中的作用一致一般用来制作页面新建一个页面<UserControl...><StackPanelHorizontalAlignment="Center"VerticalAlignment="Center"><TextBlockText="这是一个用户控件"/><ButtonName="btn1&qu......
  • Flink 1.18 Standalone 应用模式部署
    本文基于:FlinkJavaDemo1.下载https://dlcdn.apache.org/flink/flink-1.18.0/flink-1.18.0-bin-scala_2.12.tgz2.解压mkdir/usr/flinktar-zxvf/home/flink-1.18.0-bin-scala_2.12.tgz-C/usr/flink/3.推送端运行netcatnc-lp78784.将Maven的包复制到flink的lib目......