蒟蒻求助字典树关于 插入顺序对时间的影响
  • 板块学术版
  • 楼主Ghtl
  • 当前回复6
  • 已保存回复6
  • 发布时间2024/8/15 17:45
  • 上次更新2024/8/15 19:56:17
查看原帖
蒟蒻求助字典树关于 插入顺序对时间的影响
943489
Ghtl楼主2024/8/15 17:45

大致题意

小T 有个正整数序列,长度为 n, 要你求在这n个数中选择两次;

第一次选出两个不同位置的数,使得这两个数按位取与加按位取或后得到的答案最大;

第二次选择两个不同位置的数,使得这两个数按位取或加按位异或后得到的答案最大。

请求出这两个最大答案。

#include<bits/stdc++.h>
using namespace std;
int nxt[34000005][2];
int cnt;
int n;
long long a[1000005], ans,mxx,mxx2;
void insert(long long a)
{
	int u=0;
	for(int i =31;~i;--i)
	{
		if((a>>i)&1)
		{
			if(!nxt[u][1])
				nxt[u][1]=++cnt;
			u=nxt[u][1];
		}
		else
		{
			if(!nxt[u][0])
				nxt[u][0]=++cnt;
			u=nxt[u][0];
		}
	}
}

long long query(long long a)
{
	int u=0;
	long long num=0;
	for(int i =31;~i;--i)
	{
		if((a>>i)&1)
		{
			if(nxt[u][0])
			{
				u=nxt[u][0];
				num+=2LL<<i;
			}
			else
			{
				u=nxt[u][1];
				num+=1LL<<i;
			}
		}
		else
		{
			if(nxt[u][1])
			{
				u=nxt[u][1];
				num+=2LL<<i;
			}
			else
				u=nxt[u][0];
		}
	}
	return num;
}
signed main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i)
		scanf("%lld", a + i);
	for (int i = 1; i <= n; ++i) {
		if(a[i]>mxx)
		{
			mxx2=mxx;
			mxx=a[i];
		}
		else if(mxx2<a[i])
			mxx2=a[i];
	}
	sort(a + 1, a + 1 + n);
	for(int i =1;i<=n;i++)
	{
		ans=max(ans,query(a[i]));
		insert(a[i]);
	}
	printf("%lld\n%lld", mxx + mxx2, ans);
	return 0;
}

以上有排序,n=1e6,ai范围比int范围大100个一,跑了800ms。

#include<bits/stdc++.h>
using namespace std;
int nxt[34000005][2];
int cnt;
int n;
long long a[1000005], ans,mxx,mxx2;
void insert(long long a)
{
	int u=0;
	for(int i =31;~i;--i)
	{
		if((a>>i)&1)
		{
			if(!nxt[u][1])
				nxt[u][1]=++cnt;
			u=nxt[u][1];
		}
		else
		{
			if(!nxt[u][0])
				nxt[u][0]=++cnt;
			u=nxt[u][0];
		}
	}
}

long long query(long long a)
{
	int u=0;
	long long num=0;
	for(int i =31;~i;--i)
	{
		if((a>>i)&1)
		{
			if(nxt[u][0])
			{
				u=nxt[u][0];
				num+=2LL<<i;
			}
			else
			{
				u=nxt[u][1];
				num+=1LL<<i;
			}
		}
		else
		{
			if(nxt[u][1])
			{
				u=nxt[u][1];
				num+=2LL<<i;
			}
			else
				u=nxt[u][0];
		}
	}
	return num;
}
signed main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i)
		scanf("%lld", a + i);
	for (int i = 1; i <= n; ++i) {
		if(a[i]>mxx)
		{
			mxx2=mxx;
			mxx=a[i];
		}
		else if(mxx2<a[i])
			mxx2=a[i];
	}
//	sort(a + 1, a + 1 + n);
	for(int i =1;i<=n;i++)
	{
		ans=max(ans,query(a[i]));
		insert(a[i]);
	}
	printf("%lld\n%lld", mxx + mxx2, ans);
	return 0;
}

以上无排序,同样数据跑了1813ms。

求助,感觉时间都是O(nlogn),但是时间实际差了特别多,真的不理解。
本人markdown薄弱,望谅解,不喜勿喷。

2024/8/15 17:45
加载中...