CF1446C Xor Tree

一、题目

点此看题

二、解法

这种异或的题很容易想到 t i r e \tt tire tire,我们不妨把他放在 t i r e \tt tire tire 树上思考。

俗话说正难则反,我们要求点的最小删除数是可以转化成点的最大保留数的。

记住,我们要在 t i r e \tt tire tire 树上思考,坚信他的美妙性质能帮助我们解决本题。求解最大保留数可以在 t i r e \tt tire tire 树上 d p dp dp,设 f [ i ] f[i] f[i] i i i 子树内的最大保留数,首先考虑没有左 / / /右子树的情况,直接赋值就行了。

因为我们要把两个子树建立联系,所以一定是在某一边只选了一个点,才能保证连的边连接了这两个子树,所以转移方程: f [ i ] = max ⁡ ( f [ l s ] , f [ r s ] ) + 1 f[i]=\max(f[ls],f[rs])+1 f[i]=max(f[ls],f[rs])+1

#include <cstdio>
#include <iostream>
using namespace std;
const int M = 30*200005;
int read()
{
	int x=0,f=1;char c;
	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
int n,cnt,rt,f[M],a[M],ls[M],rs[M];
void insert(int &x,int v,int d)
{
	if(!x) x=++cnt;
	if(d==0)
	{
		f[x]++;
		return ;
	}
	if((v&(1<<d-1))==0)
		insert(ls[x],v,d-1);
	else
		insert(rs[x],v,d-1);
}
void dp(int x,int d)
{
	if(!x || d==0) return ;
	dp(ls[x],d-1);dp(rs[x],d-1);
	if(!ls[x]) f[x]=f[rs[x]];
	else if(!rs[x]) f[x]=f[ls[x]];
	else f[x]=max(f[ls[x]],f[rs[x]])+1;
}
signed main()
{
	n=read();
	for(int i=1;i<=n;i++)
		insert(rt,read(),31);
	dp(rt,31);
	printf("%d\n",n-f[rt]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值