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)的主要内容,如果未能解决你的问题,请参考以下文章
Jan 26 - Unique Binary Search Trees; DP; Trees; Recursion & Iteration;
Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake(线段树+离散化优化DP)