【数据结构】字典树Trie

Tire

int son[N][26], cnt[N], idx;
char str[N];
void insert(char *str){
	int p=0;
	for(int i=0;str[i];i++){
		int u=str[i]-'a';
		if(!son[p][u]) son[p][u]=++idx;
		p=son[p][u];
	}
	cnt[p]++;
}
int query(char *str){
	int p=0;
	for(int i=0;str[i];i++){
		int u=str[i]-'a';
		if(!son[p][u]) return 0;
		p=son[p][u];
	}
	return cnt[p];
}
int main(){
	cin>>n;
	while(n--){
		char op[2];
		scanf("%s%s",op,str);
		if(op[0]=='I') insert(str);
		else printf("%d\n",query(str));
	}
	return 0;
}
最大异或对
void insert(int x){
	int p=0;
	for(int i=30;i>=0;i--){
		int u=x>>i&1;
		if(!son[p][u]) son[p][u]=++idx;
		p=son[p][u];
	}
}

int query(int x){
	int p=0, res=0;
	for(int i=30;i>=0;i--){
		int u=x>>i&1;
		if(son[p][!u]){
			p=son[p][!u];
			res+=1<<i;
		}
		else p=son[p][u];
	}
	return res;
}

例题: 异或粽子

void insert(ll x){
	int p=0;
	for(int i=31;i>=0;i--){
		int u=(x>>i)&1;	siz[p]++;
		if(!son[p][u]) son[p][u]=++idx;
		p=son[p][u];
	}
	siz[p]++;
}

ll query(ll x,int rk){
	int p=0; ll res=0;
	for(int i=31;i>=0;i--){
		int u=x>>i&1;
		if(son[p][u^1]){
			if(rk<=siz[son[p][u^1]]){
				p=son[p][u^1];
				res|=1ll<<i;
			}
			else{
				rk-=siz[son[p][u^1]];
				p=son[p][u];
			}	
		}
		else p=son[p][u];
	}
	return res;
}

signed main(){
	n=read(); m=read();
	for(int i=1;i<=n;i++){
		int x=read();
		s[i]=s[i-1]^x;
	}
	for(int i=0;i<=n;i++){
		insert(s[i]);
	}
	for(int i=0;i<=n;i++){
		q.push((node){i,1,query(s[i],1)}) ;
	}
	m<<=1;
	for(int i=1;i<=m;i++){
		node t=q.top() ; q.pop(); ans+=t.w;// printf("%lld\n",ans);
		if(t.rk<n) q.push((node){t.id,t.rk+1,query(s[t.id],t.rk+1)}); 
	}
	
	printf("%lld",(ans>>1));
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值