字符串学习笔记
如题。
链接:https://gxyzoj.com/d/hzoj/training/64ae62d5016fac9fb4da7089
P366. 「一本通 2.3 例 1」Phone List
date : 2023.12.11
字典树 的模板题。这是我上洛谷搜了之后才知道的。。
早上试过哈希、数字结果都 T 了,跑大数据要9秒,下午地理课才现学字典树去写的。
字典树很好理解,也很好写,就是利用字符串 ASCLL 码去找前缀,然后往下一直建节点之类的。
参考博客:https://www.luogu.com.cn/blog/juruohyfhaha/trie-xue-xi-zong-jie
参考代码:
#include<bits/stdc++.h> using namespace std; struct node{ int son[11],sum; bool f; }trie[100110]; int n,t,num; string s[100010]; void ins(string c) { int len=c.size(),u=0; for(int i=0;i<len;i++) { int v=c[i]-'0'; if(!trie[u].son[v]) trie[u].son[v]=++num; trie[u].sum++; u=trie[u].son[v]; } trie[u].f=1; } int find(string c) { int len=c.size(),u=0; for(int i=0;i<len;i++) { int v=c[i]-'0'; if(!trie[u].son[v]) return 0; u=trie[u].son[v]; } if(trie[u].sum==0) return 0; return 1; } int main() { cin>>t; while(t--) { num=0; memset(trie,0,sizeof(trie)); scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s[i]; ins(s[i]); } for(int i=1;i<=n;i++) { if(find(s[i])) { printf("NO\n"); goto end; } } printf("YES\n"); end:; } }
字典树只有 操作和 操作,比线段树好些多了。
P367. 「一本通 2.3 例 2」The XOR Largest Pair
同样的字典树,不同的存法和读法。
这个数据结构叫做 。就是把一个数拆成二进制,然后再和字符串一样存到 里头。
代码和普通 仅有一点差别,就是一个 的节点只有两个 ,分别代表 和 。
代码:
#include<bits/stdc++.h> using namespace std; struct node{ int son[5],sum; bool f; }trie[10000005]; int cnt; int las[10000005]; void ins(int a) { int u=0; for(int i=31;i>=0;i--) { int ch=(a>>i)&1; if(!trie[u].son[ch]) trie[u].son[ch]=++cnt; trie[u].sum++; u=trie[u].son[ch]; } las[u]=a; } int find(int a) { int u=0; for(int i=31;i>=0;i--) { int v=(a>>i)&1; if(trie[u].son[v^1]) { u=trie[u].son[v^1]; } else { u=trie[u].son[v]; } // u=trie[u].son[v]; } return a^las[u]; } int num[100010]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { scanf("%d",&num[i]); ins(num[i]); } int ans=-114514191; for(int i=1;i<=n;i++) { ans=max(ans,find(num[i])); } cout<<ans; }
P368. The XOR-longest Path
依然是 。只不过在前面要先用 预处理一下节点到根的异或,然后和上题一样。
P370. 「一本通 2.3 例 3」Nikitosh 和异或
卡常的**题目。真的无语。依然是 ,两次分别从前往后和从后往前去处理异或前缀和和后缀和,然后再存到 里头。
P8819 [CSP-S 2022] 星战
一年了,终于有机会重新做这道题了。
看似和字符串没关系,实则却是没啥关系。
考虑能进行反攻的条件。首先,能进行无限次反攻,换成人话就是图里有环。但是考虑到这个是有向图,那就每个点的入度不为零。若要实现连续穿梭,则是要求整张图是一个完整的环。那就是每个点的入度都为 。
如何判定?显然,对于每次询问,维护的入度都是 修改的,但是查询所有的入度显然是 的。总复杂度 。
究其原因,是因为每个点的标识不清晰,导致必须遍历全部的点才能判断每个点的出度是否都是 。
然后,考虑如何 地判定一个状态是否是合法的,可以参考 noip模拟1的 T2,对每个点进行特异化处理,即给它一个随机化权值 ,合法状态一定满足当前入度和严格等于 。
然后就好做了,代码很短。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!