标签:int sum ss Secret maxn endd Message P2922 字典
字典树很好的一道题
这个题区别于一般的字典树前缀匹配在于
匹配的字符串可能比字典树上的长 也可能比字典树上的短
如果只是维护一个节点会被经过多少次肯定是没法解的
考虑再维护一个endd数组 表示以i节点为结尾的字符串数量
在查找的时候 比匹配字符串短的节点直接+endd数组即可
经过节点数sum就不行 因为我们只找匹配字符这一条线上的 但是sum是维护这个节点以下所有的
比匹配字符长的就可以直接加sum数组就好 这就回到了一般的字典树查找
但是要注意的是要减去endd{root} 因为这个会被加上两次 sum和endd都包含了
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=5e5+5;
int n,m,cnt;
int tr[maxn][2],sum[maxn],endd[maxn];
void insert(string x);
int serach(string x);
int main(){
cin>>m>>n;
for(int i=0;i<maxn;i++)
for(int j=0;j<2;j++)
tr[i][j]=-1;
for(int i=1;i<=m;i++){
int bi;cin>>bi;
stringstream ss;//黑科技 很好用的
for(int j=1;j<=bi;j++){
int xi;cin>>xi;
ss<<xi;
}
string s;ss>>s;
insert(s);
}
for(int i=1;i<=n;i++){
int bi;cin>>bi;
stringstream ss;
for(int j=1;j<=bi;j++){
int xi;cin>>xi;
ss<<xi;
}
string s;ss>>s;
cout<<serach(s)<<endl;
}
return 0;
}
void insert(string x){
int root=0;
for(int i=0;i<x.size();i++){
int id=x[i]-'0';
if(tr[root][id]==-1)tr[root][id]=++cnt;
root=tr[root][id];sum[root]++;
}
endd[root]++;
}
int serach(string x){
int root=0,res=0;
for(int i=0;i<x.size();i++){
int id=x[i]-'0';
if(tr[root][id]==-1)return res;
root=tr[root][id];
res+=endd[root];
}
return res-endd[root]+sum[root];
}
标签:int,sum,ss,Secret,maxn,endd,Message,P2922,字典 来源: https://www.cnblogs.com/wzxbeliever/p/16085724.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。