D. Binary Spiders(dp&Trie)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D. Binary Spiders(dp&Trie)相关的知识,希望对你有一定的参考价值。

D. Binary Spiders(dp&Trie)

题意

给定 n n n个点的点权和参数 k k k

求最大完全子图,满足任意边权 ≤ k \\le k k,边权等于两点的点权异或值。

思路

前置知识:对于 n n n个数的最小异或和对就等于相邻异或和的最小值。

所以排序后就可以 d p dp dp转移了。

这样是 O ( n 2 ) O(n^2) O(n2)的。

考虑优化,我们可以用 T r i e Trie Trie

存当前子树的最大 d p dp dp下标。

每次就遍历一遍 T r i e Trie Trie 即可。

输出答案的话就用一个数组记录。

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

#include<cstdio>
#include<algorithm>
#define M 10000010
#define N 3000010
using namespace std;
int cnt=1,f[N],lst[N],tr[M][2],t[M];
void getmax(int&a,int b)

	if(f[a]<f[b]) a=b;

const int B=30;
void insert(int x,int id)

	int now=1;
	for(int i=B;i>=0;i--)
	
		bool y=(x&(1<<i));
		if(!tr[now][y]) tr[now][y]=++cnt;
		now=tr[now][y];
		getmax(t[now],id);
	

int n,k;
struct node
	int x,y;
a[N];
bool cmp(node a,node b)return a.x<b.x;
int query(int x)

	int ans=0,now=1;
	for(int i=B;i>=0;i--)
	
		bool y=(x&(1<<i)),z=(k&(1<<i));
		if(z)
		
			if(!tr[now][y^1]) return ans;
			now=tr[now][y^1];
		
		else
		
			getmax(ans,t[tr[now][y^1]]);
			now=tr[now][y];
		
	
	getmax(ans,t[now]);
	return ans;

int main()

	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i].x),a[i].y=i;
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++)
		lst[i]=query(a[i].x),f[i]=f[lst[i]]+1,insert(a[i].x,i);
	int w=0;
	for(int i=1;i<=n;i++) getmax(w,i);
	if(f[w]==1)printf("-1");return 0;
	printf("%d\\n",f[w]);
	for(int i=w;i;i=lst[i]) printf("%d ",a[i].y);

以上是关于D. Binary Spiders(dp&Trie)的主要内容,如果未能解决你的问题,请参考以下文章

CF D. Recovering BST (区间DP)

Jan 26 - Unique Binary Search Trees; DP; Trees; Recursion & Iteration;

Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(线段树+离散化优化DP)

D. Binary Literature_Codeforces Round #715 (Div. 2)

D. Binary Literature

Codeforces 551 D. GukiZ and Binary Operations