(RERERERERERERERERERERE) BZOJ 2746: [HEOI2012]旅行问题

 二次联通门 : BZOJ 2746: [HEOI2012]旅行问题

 

 

 神TM STL的vector push_back进一个数后取出时就变成了一个很小的负数。。

调不出来了, 不调了

 

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

#define Max 100

#define Mod 1000000007LL

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 ();
    }
}

int N, M;

struct T_D 
{

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

inline int swap (int &x, int &y)
{
    int now = x;
    x = y;
    y = now;
    
}

std :: vector <int> List[Max << 1];

T_D *map[Max];

class Tree_Chain_Get_Type
{
    
    private :
    
        int size[Max];
        int deep[Max];
            
        int father[Max];
        
        int __to[Max];
        int __next[Max];
        
        int Edge_Count;
        int edge_list[Max];
        
        int top[Max];
        int Count;
        
    public :
        
        inline void Add_Edge (int from, int to)
        {
            Edge_Count ++;
            
            __to[Edge_Count] = to;
            __next[Edge_Count] = edge_list[from];
            edge_list[from] = Edge_Count;
            
            Edge_Count ++;
            __to[Edge_Count] = from;
            __next[Edge_Count] = edge_list[to];
            edge_list[to] = Edge_Count;
            
        }
        
        void Dfs_1 (int now, int __father)
        {
            
            int pos = Count ++;
            
            deep[now] = deep[__father] + 1;
            father[now] = __father;
            
            for (int i = edge_list[now]; i; i = __next[i])
                if (__to[i] != __father)
                    Dfs_1 (__to[i], now);
                    
            size[now] = Count - pos;
        }
        
        void Dfs_2 (int now, int chain)
        {
            int pos = 0;
            top[now] = chain;
            
            for (int i = edge_list[now]; i; i = __next[i])
                if (__to[i] != father[now] && size[pos] < size[__to[i]])
                    pos = __to[i];
                
            if (!pos)
                return ;
            Dfs_2 (pos, chain);
            for (int i = edge_list[now]; i; i = __next[i])
                if (__to[i] != father[now] && __to[i] != pos)
                    Dfs_2 (__to[i], __to[i]);
        }
        
        int Get_Lca (int x, int y)
        {
            for (; top[x] != top[y]; x = father[top[x]])
                if (deep[top[x]] < deep[top[y]])
                    swap (x, y);
                    
            return deep[x] < deep[y] ? x : y;
        }
        
        inline void Prepare ()
        {
            Count = 0;
            Dfs_1 (1, 0);
            Count = 0;
            Dfs_2 (1, 1);
            Count = 0;
        }
};

Tree_Chain_Get_Type Make;

class AC_Type
{

    private :
        
        T_D *Root;
        int Count;
    
    public :
    
        AC_Type ()
        {
            Root = new T_D;
            Count = 0;
            Root->number = ++ Count;
            map[Root->number] = Root;
        }
        
        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 = ++ Count;
                    map[Count] = now->child[Id];
                    now->child[Id]->value = (now->value * 26LL + Id) % Mod;
                }
                List[i].push_back (now->child[Id]->number); 
                now = now->child[Id];
            }
        }
        
        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]); 
                    Make.Add_Edge (now->child[i]->number, now->child[i]->Fail->number); 
                }
            }
        }
    
};

AC_Type AC;

char line[Max];

int main (int argc, char *argv[])
{
    int x, y;
    
    read (N);
    
    for (int i = 1; i <= N; i ++)
    {
        scanf ("%s", line);
        AC.Insert (line); 
    }
    
    AC.Build_AC ();
    
    Make.Prepare ();
    int x_1, y_1, x_2, y_2;
    
    for (read (M); M --; )
    {
        read (x_1);
        read (y_1);
        read (x_2);
        read (y_2);
        
        int now = Make.Get_Lca (List[x_1][y_1 - 1], List[x_2][y_2 - 1]);
        printf ("%lld\n", map[now]->value);
    }
    
    return 0;
}

 

转载于:https://www.cnblogs.com/ZlycerQan/p/7029373.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值