2021-05-08 Tire树练习

博客内容涉及AC代码的实现和解析,包括字符串处理、前缀树构造、位操作等算法。第一部分代码用于处理字符串插入和查询,判断字符串是否重复;第二部分解决字符串前缀问题,判断输入字符串是否为已存在字符串的前缀;第三部分实现异或和查询。博客作者通过不断调试和优化,最终成功通过所有测试用例。
摘要由CSDN通过智能技术生成

P2580 于是他错误的点名开始了

1.题意:
2.题解:

这题不难,但是我不懂为什么要开到1e6,之前一直re

3.ac代码:
#include<bits/stdc++.h>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e4+10,M=1e6+10;
int son[M][26];
int cnt[M];
int idx;
int n,m;
void insert(string s){
	int next_pos=0;
	for(int i=0;i<s.length();i++){
		int u=s[i]-'a';
		if(!son[next_pos][u]) {
			son[next_pos][u]=++idx;
		}
		next_pos=son[next_pos][u];
	}
	
	
}
void query(string s){
	int next_pos=0;
	for(int i=0;i<s.length();i++){
		int u=s[i]-'a';
		if(!son[next_pos][u]){
			cout<<"WRONG"<<endl;
			return;
		}
		next_pos=son[next_pos][u];
	}
	cnt[next_pos]++;
	if(cnt[next_pos]==1){
		cout<<"OK"<<endl;		
	}else{
		cout<<"REPEAT"<<endl;
	}
}
int main(){
	cin>>n;
	string s;
	for(int i=1;i<=n;i++){
		cin>>s;
		insert(s);
	}
	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>s;
		query(s);
	}
}

1.题意:
2.题解:

我也不知道对不对!!!,提交了半个小时都没交上去

3.ac代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e4+10,M=1e6+10;
int son[M][26];
int cnt[M];
int idx;
int n,m;
int flag=0;
void insert(string s){
	int next_pos=0,r=1;//r判断是否该字符串是前面某个字符串的前缀 
	for(int i=0;i<s.length();i++){
		int u=s[i]-'0';
		if(!son[next_pos][u]) {
			son[next_pos][u]=++idx;	
			r=0;		
		}
		next_pos=son[next_pos][u];
		if(cnt[next_pos]==1){
			flag=1;
		}
	}
	cnt[next_pos]=1;
	if(r){
		flag=1;
	}
	
	
}
void query(string s){
	int next_pos=0;
	for(int i=0;i<s.length();i++){
		int u=s[i]-'a';
		if(!son[next_pos][u]){
			
			return;
		}
		next_pos=son[next_pos][u];
	}
	
}
int main(){
	int t;
	cin>>t;
	string s;
	while(t--){
		cin>>n;
		idx=0;
		flag=0;
		memset(cnt,0,sizeof cnt);
		memset(son,0,sizeof son);
		for(int i=1;i<=n;i++){
			cin>>s;
			insert(s);
		}
		if(flag==1){
			cout<<"YES"<<endl;
		}else{
			cout<<"NO"<<endl; 
		}
	}
}

HDU 4825 Xor sum

1.题意:
2.题解:

aaaaaa!!!卡死我了,终于过了,啊啊啊啊啊啊啊啊啊啊啊啊
ll还有cin还有memset还有范围杀我aaaaaaa

3.ac代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e4+10,M=1e5+10;
int son[M*32][2];
int cnt[M];
ll idx;
int n,m;
int flag=0;
void insert(ll x){
	ll next_pos=0;
	for(int i=31;i>=0;i--){
		int u=x>>i&1;
		if(!son[next_pos][u]) son[next_pos][u]=++idx;
		next_pos=son[next_pos][u];	
	}
	
}
ll query(ll x){
	ll next_pos=0;
	ll res=0;
	for(int i=31;i>=0;i--){
		int u=x>>i&1;
		if(son[next_pos][!u]) {
			next_pos=son[next_pos][!u];
			res=(res<<1)+!u;
		}
			
		else{
			next_pos=son[next_pos][u];	
			res=(res<<1)+u;
		}
			
	}
	return res;
}
int main(){
	int t;
	scanf("%d",&t);
	for(int j=1;j<=t;j++){
		 memset(son,0,sizeof son);
		scanf("%d%d",&n,&m);
		ll x;
		for(int i=1;i<=n;i++){
			scanf("%lld",&x);
			insert(x);
	    }
	    printf("Case #%d:\n",j);
		for(int i=1;i<=m;i++){
			scanf("%lld",&x);
			printf("%lld\n",query(x));
		}
	}
	

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值