P5768
对于每个字符串,将其转换成二进制串的形式,每 位表示一个数,且每个串都有一个长度数值 ,表示需匹配的位数。
给定 次操作, 操作有两种:
- 插入操作:添加题目给出的掩码长度为 的串 。
- 查询操作:询问给出的串 在 次插入操作时的字符串匹配时匹配情况变化了几次。
很明显可以用 01trie 维护。
对于每个添加的操作,就将其拆分为 01 串的形式插入 01trie 即可。
至于查询的操作,题目直接明说了用差分,即 可以通过 求出。
稍加思考可知匹配的过程能类比单调栈的操作。
就是在 01trie 树上查询时维护一个单调栈:
- 如果当前标记在范围之内,就将栈顶所有时间更晚的标记弹出,再将当前节点入栈。
- 最后结果就是单调栈中的元素个数。
#include <bits/stdc++.h>
using namespace std;const int N=3e6;
int R(){
int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);return x;
}void W(int x){if(x>9)W(x/10);putchar(x%10+'0');}
int n,t[N][2],u,c,len,l,r,p[N],tot,f[N],cnt,mi,x,sum,g;char o;
void ip(){for(int j=0,k;j<4;++j){k=R();for(int v=7;v>=0;v--)p[j*8+v]=k%2,k>>=1;}return ;}
void in(){u=0;for(int i=0;i<len;i++){if(!t[u][p[i]])t[u][p[i]]=++tot;u=t[u][p[i]];}f[u]=++cnt;}
int q(int x){
u=0;stack <int> s;
for(int i=0;i<32;i++){
if(!t[u][p[i]])break;u=t[u][p[i]];
if(f[u]&&f[u]<=x){g=f[u];while(s.size()&&g<s.top())s.pop();s.push(g);}
}return s.size();
}int main(){
n=R();for(int i=1;i<=n;i++){
cin>>o;ip();
if(o=='A')len=R(),in();
else l=R(),r=R(),W(q(r)-q(l-1)),puts("");
}return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)