348 字
2 分钟
5-1串

字典树#

字典树(普通版本)#

以26个小写的英文字母为例子

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define fix(x) fixed<<setprecision(x)
#define int long long
using namespace std;
template<class T>
using ve=vector<T>;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
struct TIE
{
ve<ve<int>>ti;
ve<int>sum;
int cnt;
TIE(int n)
{
cnt=1;//
ti=ve<vector<int>>(n+1,ve<int>(30,-1));
sum=ve<int>(n+1,0);
}
int get_sum(char x)
{
if(x>='a'&&x<='z') return x-'a';//0-26
if(x>='A'&&x<='Z') return x-'A'+26;
return x-'0'+52;
}
void insert(const string& s)
{//
int ls=0;
for(auto x:s)
{
if(ti[ls][get_sum(x)]==-1) ti[ls][get_sum(x)]=cnt++;
ls=ti[ls][get_sum(x)];
sum[ls]++;
}
}
int query_sum(const string& s)
{
int ls=0;
for(auto x:s)
{
if(ti[ls][get_sum(x)]==-1) return 0;
ls=ti[ls][get_sum(x)];
}
return sum[ls];
}
};
void solve()
{
int n,q;cin>>n>>q;
TIE tr(3e6);
for(int i=1;i<=n;i++)
{
string s;cin>>s;
tr.insert(s);
}
while(q--)
{
string s;cin>>s;
cout<<tr.query_sum(s)<<'\n';
}
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int _=1; cin>>_;
while(_--) solve();
return 0;
}

可持久化字典树#

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define fix(x) fixed<<setprecision(x)
#define int long long
using namespace std;
template<class T>
using ve=vector<T>;
using pii = pair<int, int>;
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int n,m;
int ti[N*25][2];
int sz[N*25],rt[N*25],siz[N*25];
int cnt=0,idx=0;
void insert(int x)
{//0--24
rt[++idx]=++cnt;//开新的版本
int ls=rt[idx-1];//上一个版本
int rs=rt[idx];//当前版本
for(int i=23;i>=0;i--)
{
int j=(x>>i)&1; //
ti[rs][j^1]=ti[ls][j^1];//继承
ti[rs][j]=++cnt; //开新的节点
ls=ti[ls][j];
rs=ti[rs][j];
siz[rs]=siz[ls]+1;
}
}
int query(int l,int r,int p)
{
int ls=rt[l-1];
int rs=rt[r];
int sum=0;
for(int i=23;i>=0;i--)
{
int j=p>>i&1;
if(siz[ti[rs][j^1]]>siz[ti[ls][j^1]])
{//可以
ls=ti[ls][j^1];
rs=ti[rs][j^1];
sum+=(1<<i);
}
else
{
ls=ti[ls][j];
rs=ti[rs][j];
}
}
return sum;
}
void solve()
{
cin>>n>>m;
int ans=0;
insert(ans);
for(int i=1;i<=n;i++)
{
int x;cin>>x;
ans^=x;
insert(ans);
}
while(m--)
{
char p;cin>>p;
if(p=='A')
{
int x;cin>>x;
ans^=x;
insert(ans);
}
else
{
int l,r,x;cin>>l>>r>>x;
cout<<query(l,r,ans^x)<<'\n';
}
}
}
signed main()
{
IOS;
int _ = 1; //cin >> _;
while (_--) solve();
return 0;
}
5-1串
https://fuwari.vercel.app/posts/5-1串/
作者
nszkay
发布于
2026-01-07
许可协议
CC BY-NC-SA 4.0