hdu 4125 二叉搜索樹建立與kmp

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define FORD(i,s,t) for(int i=(s-1); i>=t; i--)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 600005;
struct NODE{
    int num;
    NODE* left, *right;
};
NODE node[MAX*2];
NODE *root;
int cnt;
int len;
map<int,int> m;
void init() {
    m.clear();
    root = NULL;
    cnt = len = 0;
}
char s[MAX*2];
char pat[7005];
int insert(NODE* &root, int num) {
    if( root == NULL ) {
        node[cnt].num = num;
        node[cnt].left = NULL;
        node[cnt].right = NULL;
        root = &node[cnt];
        return cnt++;
    }
    if( num < root->num )
        return insert(root->left, num);
    else
        return insert(root->right, num);
}

char tochar(int num) {
    return '0' + num%2;
}
void travel(NODE *root) {
    if( root == NULL )
        return ;
    s[len++] = tochar(root->num);
    travel(root->left);
    if( root->left )
        s[len++] = tochar(root->num);
    travel(root->right);
    if( root->right )
        s[len++] = tochar(root->num);
}
int pp[MAX];
bool t[MAX*2];
int stk[MAX*2];
int top;
void travel(int root) {
    memset(t, 0, sizeof(t));
    top = 0;
    stk[top++] = 0;
    while( top > 0 ) {
        int node_num = stk[top-1];
        top--;
        int num = node[node_num].num;
        s[len++] = tochar(num);
        if( t[node_num] )
            continue;
        t[node_num] = true;
        if( node[node_num].right || node[node_num].left )
            stk[top++] = node_num;
        if( node[node_num].right ) {
            int num = node[node_num].right->num;
            stk[top++] = pp[ num ];
        }
        if( node[node_num].right && node[node_num].left )
            stk[top++] = node_num;
        if( node[node_num].left ) {
            int num = node[node_num].left->num;
            stk[top++] = pp[ num ];
        }
    }
}
void kmp2(char *a, int m)
{
    pp[1] = 0;
    int j = 0;
    for(int i = 2; i <= m; ++i)
    {
        while( (j > 0)  && (a[j+1] != a[i]))
            j = pp[j];
        if( a[j+1] == a[i] ) ++j;
        pp[i] = j;
    }
}

int kmp1(char *x, char *a, int n, int m)
{
    int j = 0;
    int cnt = 0;
    for(int i = 1; i <= n; ++i)
    {
        while( (j > 0) &&  (a[j+1] != x[i]))
            j = pp[j];
        if( a[j+1] == x[i] )
            ++j;
        if(j == m){
            cnt++;
            j = pp[j];
        }
    }
    return cnt;
}

int ans() {
    kmp2(pat-1, strlen(pat));
    return kmp1(s-1, pat-1, strlen(s), strlen(pat)); 
}
int insert_(int node_num, int num) {
    NODE* root = &node[node_num];
    node[cnt].num = num;
    node[cnt].left = NULL;
    node[cnt].right = NULL;
    int pos = cnt++;
    pp[num] = pos;
    m[num] = pos;
    return pos;
}
int main() {
    int ncases, n, num;

    map<int,int>::iterator it;
    scanf("%d", &ncases);

    for(int ind=1; ind<=ncases; ind++) {
        init();
        scanf("%d", &n);
        FOR(i, 0, n) {
            scanf("%d", &num);
            if( m.size() == 0 ) {
                int pos = insert(root, num);
                m[num] = pos;
                continue;
            }
            it = m.begin();
            if( it->first > num ) {
                int pos = insert_(it->second, num);
                node[it->second].left = &node[pos];
                continue;
            }
            it = m.end();
            it--;
            if( it->first < num ) {
                int pos = insert_(it->second, num);
                node[it->second].right = &node[pos];
                continue;   
            }
            it = m.lower_bound(num);
            int ns = it->second;
            if( node[ns].left == NULL ) {
                int pos = insert_(ns, num);
                node[ns].left = &node[pos];
                continue;
            }
            if( it == m.begin() ) continue;
            it--;
            ns = it->second;
            if( node[ns].right == NULL ) {
                int pos = insert_(ns, num);
                node[ns].right = &node[pos];
                continue;
            }
        }
        scanf("%s", pat);
        travel(0);
        s[len++] = '\0';

        printf("Case #%d: %d\n", ind, ans());
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章