首页 > 代码库 > 时间不够了, 明天写

时间不够了, 明天写

 

 

 

 

#include <cstdio>
#include <cstring>
#include <queue>

#define Max 1000090

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < 0 || word > 9)
        word = getchar ();
    while (word >= 0 && word <= 9)
    {
        now = now * 10 + word - 0;
        word = getchar ();
    }
}

struct T_D
{
    T_D *child[26];

    T_D *Fail;
    int Count;
    
    int number;
    T_D ()
    {
        for (int i = 0; i < 26; i ++)
            this->child[i] = NULL;
        
        Count = 0;
        Fail = NULL;
        number = 0;
    }
};

int List[Max << 1];
int List_Cur;

bool visit[Max];

class AC_Type
{

    private :

        T_D *Root;
        int Trie_Count;

    
    public :

        void Insert (char *key)
        {
            T_D *now = Root, *pos;

            int Len = strlen (key);
            int Id;

            for (int i = 0; i < Len; i ++)
            {
                Id = key[i] - a;
                if (now->child[Id] == NULL)
                {
                    now->child[Id] = new T_D ;
                    now->child[Id]->number = ++ Trie_Count;
                }

                now = now->child[Id];
            }
            now->Count ++;
        }

        AC_Type ()
        {
            Trie_Count = 0;
            Root = new T_D ;
            Root->number = ++ Trie_Count;
        }

        void Build_AC ()
        {
            std :: queue <T_D *> Queue;

            Queue.push (Root);
            
            T_D *now, *pos;
            while (!Queue.empty ())
            {
                now = Queue.front ();
                Queue.pop ();

                pos = NULL;

                for (int i = 0; i < 26; i ++)
                {
                    if (now->child[i] == NULL)
                        continue;
                    if (now == Root)
                        now->child[i]->Fail = Root;
                    else
                    {
                        for (pos = now->Fail; pos; pos = pos->Fail)
                            if (pos->child[i])
                            {
                                now->child[i]->Fail = pos->child[i];
                                break;
                            }
                        if (pos == NULL)
                            now->child[i]->Fail = Root;
                    }
                    Queue.push (now->child[i]);
                }
            }
        }

        int Query (char *key)
        {
            T_D *now, *pos;

            int Len = strlen (key);
            int Id ;

            now = Root;
            int res = 0;
            for (int i = 0; i < Len; i ++)
            {
                Id = key[i] - a;
                for (; now->child[Id] && now != Root; now = now->Fail);
                
                now = now->child[Id];
                if (now == NULL)
                    now = Root;
                pos = now;
                for (; pos != Root && !visit[pos->number]; pos = pos->Fail)
                {
                    res += pos->Count;
                    visit[pos->number] = true;
                    List[++ List_Cur] = pos->number;
                }

                for (int i = 1; i <= List_Cur; i ++)
                    visit[List[i]] = false;

                List_Cur = 0;
                return res;
            }
        
            return res;
        }

};

AC_Type Make;

int N, Q;
char line[Max];

char __txt[Max];

int main (int argc, char *argv[])
{
    read (N);
    read (Q);
    scanf ("%s", __txt);
    for (int i = 1; i <= N; i ++)
    {
        scanf ("%s", line);
        Make.Insert (line);
    }
    for (int x, y; Q --; )
    {
        read (x);
        read (y);
        y --;
        -- x;
        int Cur = 0;
        for (int i = x; i <= y; i ++)
            line[++ Cur] = __txt[i];
        printf ("%d\n", Make.Query (line));
    }

    return 0;
}

 

时间不够了, 明天写