暴力 【p4098】[HEOI2013]ALO

Description

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

现在你拥有 n 颗宝石,每颗宝石有一个能量密度,记为 ai,这些宝石的能量 密度两两不同。现在你可以选取连续的一些宝石(必须多于一个)进行融合,设 为 ai, ai+1, …, aj,则融合而成的宝石的能量密度为这些宝石中能量密度的次大值 与其他任意一颗宝石的能量密度按位异或的值,即,设该段宝石能量密度次大值 为 k,则生成的宝石的能量密度为 max{k xor ap | ap ≠ k , i ≤ p ≤ j}

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

Input

第一行,一个整数 n,表示宝石个数

第二行,n 个整数,分别表示 a1 至 an,表示每颗宝石的能量密度,保证对于 i ≠ j 有 ai ≠ aj

Output

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

网上搜了半天关于可持久化\(01Trie\)树的题。找到了这个题,

突然发现貌似不会正解,先敲暴力.突然A了,A了.....

然后就抛弃了写正解的念头。(主要是不会啊!

我们假定当前\(a[i]\)为区间次小值,向左向右找比他大的.

如果第二次找到比他大的就\(break\)即可.

为什么不考虑当前位置为最大值?因为需要找的比较多啊...

为什么是对的?

因为我们每次扩展的话,都可以达到第一个比它大的位置。

而其他比当前数大的位置,都会与其他位置的数结合而更新.

然后每次对于\(a[i]\oplus a[j]\)\(max\)即可.

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#define R register

using namespace std;

const int gz=50008;

inline void in(int &x)
{
	int f=1;x=0;char s=getchar();
	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
	x*=f;
}

int n,a[gz],ans;

int main()
{
	in(n);
	for(R int i=1;i<=n;i++)
	{
		in(a[i]);
		R bool flg=false;
		for(R int j=i-1;j;j--)
		{
			if(a[j]>a[i])
			{
				if(!flg)flg=true;
				else break;
			}
			ans=max(ans,a[i]^a[j]);
		}
	}
	for(R int i=1;i<=n;i++)
	{
		R bool flg=false;
		for(R int j=i+1;j<=n;j++)
		{
			if(a[j]>a[i])
			{
				if(!flg)flg=true;
				else break;
			}
			ans=max(ans,a[i]^a[j]);
		}
	}
	printf("%d",ans);
}
posted @ 2018-10-30 19:18  顾z  阅读(212)  评论(0编辑  收藏  举报