首页 > 其他分享 >P4407 [JSOI2009] 电子字典

P4407 [JSOI2009] 电子字典

时间:2024-05-09 11:14:38浏览次数:11  
标签:int JSOI2009 trie 电子字典 maxn tonum P4407

题目链接:https://www.luogu.com.cn/problem/P4407

trie树+爆搜

做法:对所有文本串建树。对于编辑距离要求的三种情况,分四类在trie树上爆搜即可。


#define maxn 200010
struct trie{
    int son[maxn][26];
    int cnt[maxn];
    int idx=0;
    map<string,bool> mm;
    int vis[maxn];
    void insert(string s)
    {
        mm[s]=1;
        int u=0;
        for(int i=0;i<s.size();i++)
        {
            int c=s[i];
            if(!son[u][c]) son[u][c]=++idx;
            u=son[u][c];
        }
        cnt[u]++;//有多少个单词是以u结尾的
        // cerr<<cnt[u]<<' ';
    }
    int dfs(string s,int cur,int x,bool change)//字符串 当前trie树上的指针 当前遍历到字符串第x个位置 是否进行改变操作
    {
        if(x==s.size()&&!vis[cur]&&cnt[cur]&&change)
        {
            vis[cur]=1;
            return cnt[cur];
        }//在确定已经匹配上了一个数组才修改vis,否则只是一个前缀
        int res=0;
        if(son[cur][s[x]])//不用修改
        {
            res+=dfs(s,son[cur][s[x]],x+1,change);
        }
        if(change)//已修改但是接下来依然要修改,说明当前串不能统计进入答案,直接返回
        {
            return res;
        }
        res+=dfs(s,cur,x+1,1);//删除操作
        // cerr<<res<<" ";
        for(int i=0;i<26;i++)//插入和修改操作涉及新字符,tire树上当前节点的子节点一个个试过去
        {
            if(son[cur][i])
            {
                res+=dfs(s,son[cur][i],x+1,1);//修改操作
                res+=dfs(s,son[cur][i],x,1);//插入操作
            }
        }
        return res;
    }
    int solve(string s)
    {
        memset(vis,0,sizeof(vis));
        if(mm[s]!=0) return -1;//如果是单词就直接输出-1
        return dfs(s,0,0,0);   
    }
}T;
int n,m;
void tonum(string &s)
{
    for(int i=0;i<s.size();i++)
    {
        s[i]-='a';
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        string s;
        cin>>s;
        tonum(s);
        T.insert(s);
    }
    // cerr<<'\n';
    while(m--)
    {
        string s;
        cin>>s;
        tonum(s);
        cout<<T.solve(s)<<'\n';
    }

}

标签:int,JSOI2009,trie,电子字典,maxn,tonum,P4407
From: https://www.cnblogs.com/captainfly/p/18181664

相关文章

  • 【题解】P4307 [JSOI2009] 球队收益 / 球队预算
    P4307[JSOI2009]球队收益/球队预算题解题目传送门题意简述一共有\(n\)个球队比赛,输了赢了都会有相应的支出,现在让你安排\(m\)场比赛的输赢,是总支出最少。思路首先看到最小支出,状态不好定义,直接费用流,启动!。后文如果没有特殊说明,边的费用均为\(0\)。考虑建图,其......
  • CF765F,CF1793F,JSOI2009:区间最接近的两数
    link:https://codeforces.com/contest/765/problem/F据说是典中典问题(出现三次了)题意:给一个序列\(a_1,\dots,a_n\),有\(m\)次询问,每次询问给\(l,r(1\leql<r\leqn)\)问\(\min_{l\leqs<t\leqr}|a_s-a_t|\)\(1\leqn,m\leq10^5,a_i\leq10^9\).思路这个做法还是很妙,想......
  • 洛谷P4407 电子词典
    读完这题我马上就想到了题解trie+dfs的爆搜解法,这种解法思维难度很低,算个模拟,很容易想到但是我们稍微计算一下复杂度,就可以发现达到了\(1e8\)级别(\(26*20*20*1e4\),即对于每一个待查字符串(\(1e4\)),枚举每一个位置(\(20\)),每一个位置枚举26个字母(\(26\)),然后再在trie树上匹配(\(20\)))害......
  • P4054 [JSOI2009] 计数问题
    二维树状数组板子,C[color][x][y] #include<bits/stdc++.h>usingnamespacestd;constintN=403,M=2e5+4;#defineintlonglongintA[N][N],c[101][N......
  • JSOI2009 题解
    Count二维树状数组板子题,开\(c\)个二维树状数组即可过。可以通过离线对每个权值单独操作做到只开一个二维树状数组。如果空间要求更紧的话可以cdq分治做到只开一个......
  • 拼多多 2020校招 多多的电子字典(字典树前缀搜索,DP)
    多多鸡打算造一本自己的电子字典,里面的所有单词都只由a和b组成。每个单词的组成里a的数量不能超过N个且b的数量不能超过M个。多多鸡的幸运数字是K,它打算把所有满足条件的......
  • P4054 [JSOI2009] 计数问题
    传送门二维树状数组板子题(大概?)只要再多开一维\(c\)来存储该点的权值就可以了。这里的树状数组\(a[i][j][c]\)表示以第\(i\)行,第\(j\)列为右下角,权值为\(c\)的点......
  • P4407 [JSOI2009] 电子字典 题解
    题目:P4407这题差不多就是P1688的改版。参考一下我在P1688的做法,我们继续使用Hash,然后只要考虑如何去重就好了。于是就有了这个暴力的想法:#代表修改,@代表添加,$代......
  • luoguP4407 [JSOI2009] 电子字典 解题报告
    传送门题意对于多个字符串,查询其在字典树上的存在性或删除/插入/替换一个字符后存在的个数。思路存在性好说,直接在Trie树上做一遍查找即可。那剩下的三个操作怎么办......