【字符串】tire树 kmp

1.tire树

N*31

数组开多大

1.1存储字符串

835. Trie字符串统计 - AcWing题库

#include<iostream>
using  namespace std;


int son[3200001][26];
int cnt[3200001];
int idx=0;


void insertt(string str){

    int p=0;
    for(int i=0;str[i];i++){
        int u=str[i]-'a';
        if(!son[p][u])son[p][u]=++idx;
        p=son[p][u];
//还可以cnt[p]++放这里,统计前缀
    }
     cnt[p]++;
}

int getcnt(string str){
int p=0;
for(int i=0;str[i];i++){
int u=str[i]-'a';
        if(!son[p][u])return 0;
        p=son[p][u];

}
return cnt[p];
}


int main(){


int n;
cin>>n;
while(n--){
    char q;string str;
    cin>>q>>str;
    if(q=='I')insertt(str);
    if(q=='Q')cout<<getcnt(str)<<endl;
}
}

1.2存int数

算异或,因为是异或,不能简单更新最大最小值这种

#include<iostream>
#include<vector>
using namespace std;

int son[3200001][2];
int idx=0;
vector<int> z;

void insertt(int x){
int p=0;
for(int i=30;i>=0;i--){
    int u=(x>>i)&1;
    if(!son[p][u])son[p][u]=++idx;
    p=son[p][u];
}


}


int getyihuo(int x){
int p=0;int res=0;
for(int i=30;i>=0;i--){
    int u=!((x>>i)&1);
    if(son[p][u]){
            res+=1<<i;
    p=son[p][u];}
    else {
        p=son[p][!u];
    }
}
return res;

}
int n;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
z.push_back(x);
insertt(x);
}

int ans=0;
for(auto i:z){
    ans=max(ans,getyihuo(i));
}
cout<<ans;

}

2.kmp 

for (int i = 2, j = 0; i <= m; i ++ )
{
    while (j && p[i] != p[j + 1]) j = ne[j];
    if (p[i] == p[j + 1]) j ++ ;
    ne[i] = j;
}


for (int i = 1, j = 0; i <= n; i ++ )
{
    while (j && s[i] != p[j + 1]) j = ne[j];
    if (s[i] == p[j + 1]) j ++ ;
    if (j == m)
    {
        j = ne[j];
    
    }

3.例题

Oulipo - POJ 3461 - Virtual Judge (vjudge.net.cn)

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;

int ans=0;
int n,m;
char s[1000001];
char p[10001];
int ne[10001];

void kmp(){


for(int i=2,j=0;i<=n;i++){
    while(j&&p[i]!=p[j+1])j=ne[j];

    if(p[i]==p[j+1])j++;

    ne[i]=j;
}

for(int i=1,j=0;i<=m;i++){
while(j&&s[i]!=p[j+1])j=ne[j];

    if(s[i]==p[j+1])j++;

    if(j==n){ans++;
            j=ne[j];}
}

}
int main(){

int t;cin>>t;

while(t--){
        ans=0;

scanf("%s%s",p+1,s+1);
//cin>>p+1>>s+1;
n=m=0;
for(n=1;p[n];n++);
n--;
for(m=1;s[m];m++);
m--;
        //cout<<n<<" "<<m<<" ";
kmp();
cout<<ans<<endl;
}

}

Seek the Name, Seek the Fame - POJ 2752 - Virtual Judge (vjudge.net.cn)

过不了

之后还得看字符串哈希

Power Strings - POJ 2406 - Virtual Judge (vjudge.net.cn)

熟悉ne[]用处

Period - POJ 1961 - Virtual Judge (vjudge.net.cn)

与上题类似,i/(i-ne[i])周期

亲和串 - HDU 2203 - Virtual Judge (vjudge.net.cn)

#include<iostream>
using namespace std;


int main(){

while(1){
char s[200001]={0};
char p[100001]={0};
int ne[100001]={0};
if(scanf("%s%s",s+1,p+1)==EOF)break;
int n=0;int m=0;
while(s[++m]);m--;
while(p[++n]);n--;
//cout<<m<<n;

for(int i=1;i<=m;i++)s[i+m]=s[i];
m*=2;


for(int i=2,j=0;i<=n;i++){
    while(j&&p[i]!=p[j+1])j=ne[j];

    if(p[i]==p[j+1])j++;

    ne[i]=j;
}


bool flag=0;
for(int i=1,j=0;i<=m;i++){
 while(j&&s[i]!=p[j+1])j=ne[j];

    if(s[i]==p[j+1])j++;

    if(j==n){
            flag=1;
    break;
    }

}

if(flag)cout<<"yes"<<endl;
else cout<<"no"<<endl;


}



}

P6018 [Ynoi2010] Fusion tree - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P6623 [省选联考 2020 A 卷] 树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

Trie 树 基础练习 - 题单 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

Trie字典树习题(一本通) - shirlybabyyy - 博客园 (cnblogs.com)

P4551 最长异或路径 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

字典树(Trie树)模板以及简单的入门题总结_trie树模板-CSDN博客

单词数 - HDU 2072 - Virtual Judge (vjudge.net.cn)

?wa

Shortest Prefixes - POJ 2001 - Virtual Judge (vjudge.net.cn)

?complite error

3221. 最佳文章 - AcWing题库

之后做一下

Phone List - POJ 3630 - Virtual Judge (vjudge.net.cn)

一会tle一会mle一会comp error的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值