字典树模版求调

P8306 【模板】字典树

二叉苹果树 @ 2022-11-23 01:40:03

思路和第一篇题解相同,但是5WA + 1TLE求助

#include<bits/stdc++.h>
#define MAXN 3000005
int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch))
    {
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    return x * f;
}

char s[MAXN];
int trie[MAXN][65], sum[MAXN], tot;

int change(char c)
{
    if(c >= 'A' && c <= 'Z')
        return c - 'A';
    else if(c >= 'a' && c <= 'z')
        return c - 'a' + 26;
    else
        return c - '0' + 52;
}

void insert(char *str)
{
    int u = 0;
    int len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int a = change(str[i]);
        if(trie[u][a] == 0)
            trie[u][a] = ++tot;
        u = trie[u][a];
        sum[u]++;
    }
}

int find(char *str)
{
    int u = 0;
    int len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int a = change(str[i]);
        if(trie[u][a] == 0)
            return 0;
        u = trie[u][a];
    }
    return sum[u];
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0), std::cout.tie(0);
    int t = read();
    while(t--)
    {
        int n = read(), q = read();
        for(int i = 0; i <= tot; i++)
        {
            for(int j = 0; j <= 65; j++)
                trie[i][j] = 0;
            sum[i] = 0;
        }
        tot = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            insert(s);
        }
        for(int i = 1; i <= q; i++)
        {
            scanf("%s", s);
            std::cout << find(s) << std::endl;
        }
    }
    return 0;
}

by 二叉苹果树 @ 2022-11-23 02:19:29

upd

36pts

#include <bits/stdc++.h>
#define MAXN 3000005
#define MAXA 65

char s[MAXN];
int tot, trie[MAXN][MAXA], sum[MAXN];

int change(char ch)
{
    if(ch >= 'A' || ch <= 'Z')
        return ch - 'A';
    else if(ch >= 'a' && ch <= 'z')
        return ch - 'a' + 26;
    else
        return ch - '0' + 52;
}

void insert(char *str)
{
    int u = 0,len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int c = change(str[i]);
        if(trie[u][c] == 0)
            trie[u][c] = ++tot;
        u = trie[u][c];
        sum[u]++;
    }
}
int find(char *str)
{
    int u = 0,len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int c = change(str[i]);
        if(trie[u][c] == 0)
            return 0;
        u = trie[u][c];
    }
    return sum[u];
}

int main()
{
    int t, n, q;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &q);
        for(int i = 0; i <= tot; i++)
        {
            for(int j = 0; j <= 125; j++)
                trie[i][j] = 0;
            sum[i] = 0;
        }
        tot = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            insert(s);
        }
        for(int i = 1; i <= q; i++)
        {
            scanf("%s", s);
            printf("%d\n", find(s));
        }
    }
}

by TianLuen @ 2022-11-23 07:23:47

@二叉苹果树 你那个大写字母判断了个什么东西((


by TianLuen @ 2022-11-23 07:24:40

ch >= 'A' || ch <= 'Z'

改成

ch >= 'A' && ch <= 'Z'

即可


by cmeet @ 2022-11-23 07:27:40

这种小题加什么快读? 删了就对了,还有cin解绑之后就不要用scanf,会wa

#include<bits/stdc++.h>
#define MAXN 3000005
using namespace std;
char s[MAXN];
int trie[MAXN][65], sum[MAXN], tot;

int change(char c)
{
    if(c >= 'A' && c <= 'Z')
        return c - 'A';
    else if(c >= 'a' && c <= 'z')
        return c - 'a' + 26;
    else
        return c - '0' + 52;
}

void insert(char *str)
{
    int u = 0;
    int len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int a = change(str[i]);
        if(trie[u][a] == 0)
            trie[u][a] = ++tot;
        u = trie[u][a];
        sum[u]++;
    }
}

int find(char *str)
{
    int u = 0;
    int len = strlen(str);
    for(int i = 0; i < len; i++)
    {
        int a = change(str[i]);
        if(trie[u][a] == 0)
            return 0;
        u = trie[u][a];
    }
    return sum[u];
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,q;
        cin>>n>>q;
        for(int i = 0; i <= tot; i++)
        {
            for(int j = 0; j <= 65; j++)
                trie[i][j] = 0;
            sum[i] = 0;
        }
        tot = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            insert(s);
        }
        for(int i = 1; i <= q; i++)
        {
            scanf("%s", s);
            std::cout << find(s) << std::endl;
        }
    }
    return 0;
}

by TianLuen @ 2022-11-23 08:12:18

@cmeet 这个不是快读,是ASCII码转转化然后压一点空间


|