现在的位置: 首页 > 综合 > 正文

HDU 4125 NlogN查找二叉树的生成

2013年08月25日 ⁄ 综合 ⁄ 共 1729字 ⁄ 字号 评论关闭

题意:题目给定一颗二叉树,前序遍历二叉树的时候产生一个01的欧拉序列,输出某个01串在此序列中出现了几次。

总结:真是弱。。。。我居然模拟查找二叉树的生成,这可能退化到N^2。。。,引用了一个结论:

http://www.cppblog.com/hanfei19910905/archive/2012/07/02/181144.html

nlogn的算法生成静态二叉树,mark一下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#pragma comment(linker, "/STACK:36777216")
using namespace std;

const int N = 600050;

char s[N << 1],p[N];
int next[N],n,a[N],idx,lenp,lens,tot;
int left[N],right[N],stack[N],top;
bool vis[N];
set<int> myset;

void init(int key){
    myset.clear();
    top = 0;
    for(int i = 1;i <= n;i ++)
        left[i] = right[i] = -1;
    myset.insert(key);
}

void insert(int key){
    // printf("key:%d  ",key);
    myset.insert(key);
    set<int> ::iterator less,more;
    more = less = myset.lower_bound(key);
    if(less != myset.begin()){
        less --;
        if(right[*less] == -1) {right[*less] = key;
            // printf("less:%d\n",*less);
            return ;
        }
    }
    more ++;
    if(more != myset.end() && left[*more] == -1) left[*more] = key;
    // printf("more:%d\n",*more);
}

void setNext(){
    int j = 0 , k = -1;
    next[j] = k;
    while(j < lenp){
        if(k == -1 || p[j] == p[k]){
            if(p[j + 1] == p[k + 1]) next[++ j] = next[++ k];
            else next[++ j] = ++k;
        }
        else k = next[k];
    }
}

void dfs(int cur){
    memset(vis,false,sizeof(vis));
    top = 0;
    stack[++ top] = cur;
    while(!vis[cur]){
        int u = stack[top];
        s[lens ++] = '0' + (u & 1);
        int v = left[u];
        if(v != -1 && !vis[v]) {stack[++ top] = v;continue;}
        v = right[u];
        if(v != -1 && !vis[v]) {stack[++ top] = v; continue;}
        top --;
        vis[u] = 1;
    }
}

int kmp(){
    int i = 0,j = 0;
    int Count = 0;
    while(i < lens){
        if(j == -1 || s[i] == p[j]){
            i ++,j ++;
            if(j == lenp) Count ++;
        }
        else j = next[j];
    }
    return Count;
}

int main(){
    // freopen("input.txt","r",stdin);
    int cas;
    scanf("%d",&cas);
    for(int t = 1;t <= cas;t ++){
        scanf("%d",&n);
        for(int i = 0;i < n;i ++)
            scanf("%d",&a[i]);
        scanf("%s",p);
        init(a[0]);
        for(int i = 1;i < n;i ++)
            insert(a[i]);
        // printf("LLLL:%d\n",left[5]);
        lens = 0;
        dfs(a[0]);
        s[lens] = '\0';
        lenp = strlen(p);
        // printf("s:%s\n",s);
        setNext();
        int ans = kmp();
        printf("Case #%d: %d\n",t,ans);
    }
    return 0;
}

抱歉!评论已关闭.